# 📡 iRacing Telemetry API(IRSDK)完整规范 ## 一、概述 iRacing 的遥测系统通过 **共享内存映射文件(Memory-Mapped File)** 工作,所有数据是**只读**的。API 版本当前为 **IRSDK_VER = 2**。 ### 三种数据通道 | 通道 | 形式 | 频率 | 说明 | |---|---|---|---| | **Live Telemetry** | 共享内存 `Local\IRSDKMemMapFileName` | 60Hz(或 360Hz) | 实时变量数据,三缓冲机制 | | **Session String** | 共享内存中的 YAML 字符串 | 变更时更新 | 会话元数据(赛道、车手、天气等) | | **Disk Telemetry (.ibt)** | 二进制文件 | 60Hz | 按 `Alt+L` 录制,结构等同于 Live 数据 | ### 启用遥测 在 iRacing 的 `app.ini` 中确认: ```ini [External Telemetry] enableTelemetry=1 # 启用遥测 enableIRSDKTelemetry=1 # 启用 IRSDK ``` --- ## 二、核心架构 ### 共享内存布局 ``` [irsdk_header] ↓ [irsdk_varHeader[0] ... irsdk_varHeader[numVars-1]] ↓ [Session Info YAML String] ↓ [irsdk_varBuf[0]] → [Telemetry Data Line 0] [irsdk_varBuf[1]] → [Telemetry Data Line 1] [irsdk_varBuf[2]] → [Telemetry Data Line 2] [irsdk_varBuf[3]] → [Telemetry Data Line 3] (IRSDK_MAX_BUFS = 4) ``` - **三缓冲**:模拟器写满一个缓冲区后立即切到下一个,给客户端 16ms+ 窗口来读取 - **同步事件**:`Local\IRSDKDataValidEvent` — 新数据就绪时触发 ### 字节序与编码 - **字节序**:Little Endian - **YAML 编码**:UTF-8 - **对齐**:16 字节对齐 - **变量名最大长**:`IRSDK_MAX_STRING = 32` - **描述最大长**:`IRSDK_MAX_DESC = 64` --- ## 三、数据结构 ### 1. irsdk_header(主头部) ```c struct irsdk_header { int ver; // API 版本 = 2 int status; // 位字段 (irsdk_stConnected = 1) int tickRate; // tick 频率 (60 或 360) // 会话信息(变更时更新) int sessionInfoUpdate; // 会话信息变更计数 int sessionInfoLen; // YAML 字符串长度(字节) int sessionInfoOffset; // 距头部的偏移 // 遥测变量 int numVars; // 变量数量 int varHeaderOffset; // varHeader 数组偏移 int numBuf; // 缓冲区数量(4) int bufLen; // 每行字节数 int pad1[2]; // 16 字节对齐 irsdk_varBuf varBuf[IRSDK_MAX_BUFS]; // 4 个缓冲区 }; ``` ### 2. irsdk_varHeader(变量描述头) ```c struct irsdk_varHeader { int type; // irsdk_VarType 枚举 int offset; // 在缓冲区行中的偏移 int count; // 数组元素数(标量 = 1) bool countAsTime; char pad[3]; // 16 字节对齐 char name[IRSDK_MAX_STRING]; // 变量名,如 "Speed" char desc[IRSDK_MAX_DESC]; // 描述,如 "GPS vehicle speed" char unit[IRSDK_MAX_STRING]; // 单位,如 "m/s" }; ``` ### 3. irsdk_varBuf(数据缓冲区) ```c struct irsdk_varBuf { int tickCount; // 检测数据更新 int bufOffset; // 距头部的偏移 int pad[2]; // 16 字节对齐 }; ``` ### 4. irsdk_VarType(变量类型) | 枚举值 | 类型 | 字节数 | |---|---|---| | `irsdk_char = 0` | char | 1 | | `irsdk_bool` | bool | 1 | | `irsdk_int` | int32 | 4 | | `irsdk_bitField` | bitfield (int32) | 4 | | `irsdk_float` | float32 | 4 | | `irsdk_double` | float64 | 8 | ### 5. irsdk_diskSubHeader(仅 .ibt 文件) ```c struct irsdk_diskSubHeader { time_t sessionStartDate; double sessionStartTime; double sessionEndTime; int sessionLapCount; int sessionRecordCount; }; ``` --- ## 四、Session String(YAML 结构) YAML 字符串通过 `irsdk_getSessionInfoStr()` 获取,包含以下顶级节点: ### WeekendInfo ```yaml WeekendInfo: TrackName: "suzuka" TrackID: 123 TrackLength: "5807 m" TrackDisplayName: "Suzuka International Racing Course" TrackCity: "Suzuka" TrackCountry: "JPN" TrackNumTurns: 18 TrackPitSpeedLimit: "80 kph" TrackType: "road" TrackWeatherType: "Dynamic" TrackSkies: "Partly Cloudy" TrackSurfaceTemp: "38 C" TrackAirTemp: "25 C" TrackWindVel: "3 m/s" TrackWindDir: "180 deg" TrackRelativeHumidity: "55 %" TrackFogLevel: "0 %" SeriesID: 100 SeasonID: 2024 SessionID: 456 SubSessionID: 789 LeagueID: 0 Official: 1 RaceWeek: 5 EventType: "Race" Category: "Road" SimMode: "full" TeamRacing: 0 MinDrivers: 6 MaxDrivers: 26 NumCarClasses: 1 NumCarTypes: 3 WeekendOptions: NumStarters: 20 StartingGrid: "2x2" QualifyScoring: "single" CourseCautions: "full" StandingStart: 0 Restarts: "singleFile" WeatherType: "Dynamic" Skies: "Partly Cloudy" WindDirection: "180 deg" WindSpeed: "3 m/s" WeatherTemp: "25 C" RelativeHumidity: "55 %" FogLevel: "0 %" Unofficial: 0 IsFixedSetup: 0 HardcoreLevel: 1 ``` ### SessionInfo ```yaml SessionInfo: Sessions: - SessionNum: 0 SessionLaps: "unlimited" SessionTime: "30 min" SessionType: "Practice" ResultsPositions: [] ResultsFastestLap: [] - SessionNum: 1 SessionLaps: "2 laps" SessionTime: "10 min" SessionType: "Lone Qualify" - SessionNum: 2 SessionLaps: "12 laps" SessionTime: "30 min" SessionType: "Race" ``` ### DriverInfo ```yaml DriverInfo: DriverCarIdx: 0 DriverCarIdleRPM: 3500.0 DriverCarRedLine: 9500.0 DriverCarSLFirstRPM: 8500.0 DriverCarSLShiftRPM: 9000.0 DriverCarSLLastRPM: 9500.0 DriverCarSLBlinkRPM: 9200.0 Drivers: - CarIdx: 0 UserName: "John Doe" AbbrevName: "J. Doe" Initials: "JD" CarNumber: "23" CarPath: "mercedesamggt3" CarClassID: 1 IRating: 2500 LicString: "A 4.99" IsSpectator: 0 ``` ### CameraInfo ```yaml CameraInfo: Groups: - GroupNum: 1 GroupName: "TV1" Cameras: - CameraNum: 1 CameraName: "TV1_Turn1" ``` ### SplitTimeInfo ```yaml SplitTimeInfo: Sectors: - SectorNum: 0 SectorStartPct: 0.0 - SectorNum: 1 SectorStartPct: 0.35 - SectorNum: 2 SectorStartPct: 0.70 ``` --- ## 五、核心遥测变量列表(完整) ### 🏎️ 玩家车辆控制 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `SteeringWheelAngle` | float | rad | 方向盘转角 | | `Throttle` | float | % (0-1) | 油门(处理后的) | | `Brake` | float | % (0-1) | 刹车(处理后的) | | `Clutch` | float | % (0-1) | 离合 | | `Gear` | int | — | -1=R,0=N,1~n=前进档 | | `RPM` | float | revs/min | 引擎转速 | | `ThrottleRaw` | float | % (0-1) | 原始油门输入 | | `BrakeRaw` | float | % (0-1) | 原始刹车输入 | | `HandbrakeRaw` | float | % (0-1) | 原始手刹输入 | | `Speed` | float | m/s | GPS 车速 | | `OnPitRoad` | bool | — | 是否在维修区通道 | ### 📐 位置与运动 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `Yaw` | float | rad | 偏航角 | | `YawNorth` | float | rad | 相对北方的偏航角 | | `Pitch` | float | rad | 俯仰角 | | `Roll` | float | rad | 侧倾角 | | `YawRate` / `YawRate_ST` | float | rad/s | 偏航率(ST=子tick精度) | | `PitchRate` / `PitchRate_ST` | float | rad/s | 俯仰率 | | `RollRate` / `RollRate_ST` | float | rad/s | 侧倾率 | | `VelocityX` / `VelocityX_ST` | float | m/s | X 方向速度 | | `VelocityY` / `VelocityY_ST` | float | m/s | Y 方向速度 | | `VelocityZ` / `VelocityZ_ST` | float | m/s | Z 方向速度 | | `LatAccel` / `LatAccel_ST` | float | m/s² | 横向加速度 | | `LongAccel` / `LongAccel_ST` | float | m/s² | 纵向加速度 | | `VertAccel` / `VertAccel_ST` | float | m/s² | 垂向加速度 | > `_ST` 后缀变量提供 **子 tick 精度**,适合运动平台等精密场景。 ### ⏱️ 圈速与计时 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `Lap` | int | — | 当前圈号 | | `LapCompleted` | int | — | 已完成圈数 | | `LapDist` | float | m | 当前圈已跑距离 | | `LapDistPct` | float | % | 当前圈完成百分比 | | `RaceLaps` | int | — | 比赛中已完成圈数 | | `LapBestLap` | int | — | 最佳圈号 | | `LapBestLapTime` | float | s | 最佳圈速 | | `LapLastLapTime` | float | s | 上一圈用时 | | `LapCurrentLapTime` | float | s | 当前圈用时(F3 黑盒) | | `LapBestNLapLap` | int | — | 最佳 N 圈均值的最后一圈 | | `LapBestNLapTime` | float | s | 最佳 N 圈平均时间 | | `LapLastNLapTime` | float | s | 最近 N 圈平均时间 | | `LapLasNLapSeq` | int | — | 连续干净圈数 | ### 🎯 Delta 时间 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `LapDeltaToBestLap` | float | s | 与个人最佳圈的差距 | | `LapDeltaToBestLap_DD` | float | s/s | 差距变化率 | | `LapDeltaToBestLap_OK` | bool | — | delta 数据是否有效 | | `LapDeltaToOptimalLap` | float | s | 与理论最佳圈的差距 | | `LapDeltaToOptimalLap_DD` | float | s/s | 差距变化率 | | `LapDeltaToOptimalLap_OK` | bool | — | 是否有效 | | `LapDeltaToSessionBestLap` | float | s | 与全场最佳圈差距 | | `LapDeltaToSessionBestLap_DD` | float | s/s | 差距变化率 | | `LapDeltaToSessionBestLap_OK` | bool | — | 是否有效 | | `LapDeltaToSessionOptimalLap` | float | s | 与全场理论最佳差距 | | `LapDeltaToSessionLastlLap` | float | s | 与全场上一圈差距 | ### ⛽ 引擎 & 燃油 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `FuelLevel` | float | L | 剩余油量(升) | | `FuelLevelPct` | float | % | 剩余油量百分比 | | `FuelPress` | float | bar | 燃油压力 | | `FuelUsePerHour` | float | kg/h | 瞬时油耗率 | | `ManifoldPress` | float | bar | 进气歧管压力 | | `OilLevel` | float | L | 机油液位 | | `OilPress` | float | bar | 机油压力 | | `OilTemp` | float | °C | 机油温度 | | `WaterLevel` | float | L | 冷却液液位 | | `WaterTemp` | float | °C | 冷却液温度 | | `Voltage` | float | V | 电压 | | `EngineWarnings` | bitfield | — | 引擎警告灯(见下文) | | `BrakeABSactive` | bool | — | ABS 是否激活 | ### 🛞 轮胎数据(每轮 LF/RF/LR/RR) 设 `X` ∈ {LF, RF, LR, RR}: | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `XcoldPressure` | float | kPa | 冷胎压 | | `Xpressure` | float | kPa | 当前胎压 | | `XtempCL/M/R` | float | °C | 胎面左/中/右温度 | | `XwearL/M/R` | float | % | 胎面左/中/右磨损 | | `XbrakeLinePress` | float | bar | 刹车管压力 | | `XshockDefl` | float | mm | 悬挂压缩量 | | `XshockVel` | float | mm/s | 悬挂速度 | | `XrideHeight` | float | mm | 行驶高度 | | `Xspeed` | float | rad/s | 轮速 | ### 🎛️ 力反馈 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `SteeringWheelTorque` | float | N·m | 转向轴输出扭矩 | | `SteeringWheelTorque_ST` | float | N·m | 转向轴扭矩(子tick) | | `SteeringWheelPctTorque` | float | % | FFB 扭矩百分比(无符号) | | `SteeringWheelPctTorqueSign` | float | % | FFB 扭矩百分比(有符号) | | `SteeringWheelPctTorqueSignStops` | float | % | FFB 扭矩百分比(含止挡) | | `SteeringWheelPctDamper` | float | % | FFB 阻尼百分比 | | `SteeringWheelAngleMax` | float | rad | 方向盘最大转角 | | `SteeringWheelPeakForceNm` | float | N·m | FFB 峰值力映射 | | `SteeringWheelMaxForceNm` | float | N·m | 最大力 | | `SteeringWheelUseLinear` | bool | — | 是否线性模式 | ### 🏁 会话状态 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `SessionTime` | double | s | 当前会话已过时间 | | `SessionTimeRemain` | double | s | 会话剩余时间 | | `SessionTimeTotal` | double | s | 会话总时间 | | `SessionLapsRemain` | int | — | 剩余圈数 | | `SessionLapsRemainEx` | int | — | 扩展剩余圈数 | | `SessionLapsTotal` | int | — | 总圈数 | | `SessionNum` | int | — | 会话序号 | | `SessionState` | int | — | 会话状态(见枚举) | | `SessionUniqueID` | int | — | 会话唯一 ID | | `SessionFlags` | bitfield | — | 旗语(见下文) | | `SessionTick` | int | — | Tick 计数 | | `SessionTimeOfDay` | float | s | 赛道时间 | ### 🚩 旗语 & 状态 **SessionFlags** 位字段: | 位标记 | 含义 | |---|---| | `0x00000001` | 🏁 方格旗 | | `0x00000002` | ⬜ 白旗 | | `0x00000004` | 🟩 绿旗 | | `0x00000008` | 🟨 黄旗 | | `0x00000010` | 🟥 红旗 | | `0x00000020` | 🟦 蓝旗 | | `0x00000040` | 💥 碎片 | | `0x00000100` | 🟨 黄旗挥动 | | `0x00000200` | 绿旗前最后一圈 | | `0x00004000` | ⚠️ Full Course Caution | | `0x00010000` | ⬛ 黑旗 | | `0x00020000` | ❌ DSQ | | `0x10000000` | 🔴 发车灯隐藏 | | `0x20000000` | 🔴 发车灯就绪 | | `0x40000000` | 🔴 发车灯 Set | | `0x80000000` | 🟢 发车灯 Go | **EngineWarnings** 位字段: | 位标记 | 含义 | |---|---| | `0x0001` | 水温警告 | | `0x0002` | 燃油压力警告 | | `0x0004` | 机油压力警告 | | `0x0008` | 引擎熄火 | | `0x0010` | Pit Speed Limiter | | `0x0020` | 转速限制器激活 | | `0x0040` | 油温警告 | ### 🚗 多车数据(CarIdx 数组,最多 64 辆车) | 变量名 | 类型 | 说明 | |---|---|---| | `CarIdxLap` | int[] | 每辆车的圈数 | | `CarIdxLapCompleted` | int[] | 每辆车已完成圈数 | | `CarIdxLapDistPct` | float[] | 每辆车的位置百分比 | | `CarIdxPosition` | int[] | 每辆车的排名 | | `CarIdxClassPosition` | int[] | 组别排名 | | `CarIdxClass` | int[] | 组别 ID | | `CarIdxF2Time` | float[] | 与领先者的差距(或最快圈速) | | `CarIdxEstTime` | float[] | 预计到达当前位置的时间 | | `CarIdxLastLapTime` | float[] | 上一圈时间 | | `CarIdxBestLapTime` | float[] | 最佳圈时间 | | `CarIdxBestLapNum` | int[] | 最佳圈号 | | `CarIdxSteer` | float[] | 方向盘转角 | | `CarIdxRPM` | float[] | 引擎转速 | | `CarIdxGear` | int[] | 档位 | | `CarIdxOnPitRoad` | bool[] | 是否在维修区 | | `CarIdxTrackSurface` | int[] | 赛道位置类型 | | `CarIdxTrackSurfaceMaterial` | int[] | 路面材质 | | `CarIdxTireCompound` | int[] | 轮胎配方 | | `CarIdxP2P_Status` | bool[] | Push-to-Pass 状态 | | `CarIdxP2P_Count` | int[] | Push-to-Pass 剩余次数 | ### 🛑 进站 & 维修 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `PitsOpen` | bool | — | 维修区是否开放 | | `PitstopActive` | bool | — | 正在进站 | | `PitRepairLeft` | float | s | 强制维修剩余时间 | | `PitOptRepairLeft` | float | s | 可选维修剩余时间 | | `PitSvFlags` | bitfield | — | 进站服务勾选 | | `PitSvLFP/RFP/LRP/RRP` | float | kPa | 指定胎压 | | `PitSvFuel` | float | L | 指定加油量 | | `PitSvTireCompound` | int | — | 指定轮胎配方 | | `FastRepairUsed` | int | — | 已用快速维修次数 | | `FastRepairAvailable` | int | — | 可用快速维修次数 | | `PlayerCarInPitStall` | bool | — | 玩家在维修位 | | `PlayerCarPitSvStatus` | int | — | 进站服务状态 | **PitSvFlags** 位字段: | 位标记 | 含义 | |---|---| | `0x0001` | 左前换胎 | | `0x0002` | 右前换胎 | | `0x0004` | 左后换胎 | | `0x0008` | 右后换胎 | | `0x0010` | 加油 | | `0x0020` | 撕膜 | | `0x0040` | 快速维修 | ### 🌦️ 天气 & 环境 | 变量名 | 类型 | 单位 | 说明 | |---|---|---|---| | `TrackTemp` | float | °C | 赛道温度(起终点) | | `TrackTempCrew` | float | °C | 赛道温度(Pit 区) | | `TrackWetness` | float | — | 赛道湿度级别 | | `AirTemp` | float | °C | 空气温度 | | `AirDensity` | float | kg/m³ | 空气密度 | | `AirPressure` | float | Hg | 气压 | | `WindVel` | float | m/s | 风速 | | `WindDir` | float | rad | 风向 | | `RelativeHumidity` | float | % | 相对湿度 | | `FogLevel` | float | % | 雾级别 | | `WeatherType` | int | — | 0=恒定,1=动态 | | `Skies` | int | — | 0=晴,1=少云,2=多云,3=阴 | ### 🎥 回放 & 系统 | 变量名 | 类型 | 说明 | |---|---|---| | `IsReplayPlaying` | bool | 是否回放中 | | `ReplayFrameNum` | int | 回放当前帧号 | | `ReplayFrameNumEnd` | int | 回放末尾帧号 | | `ReplayPlaySpeed` | int | 回放速度 | | `ReplayPlaySlowMotion` | bool | 是否慢动作 | | `ReplaySessionTime` | double | 回放中的会话时间 | | `ReplaySessionNum` | int | 回放会话序号 | | `IsOnTrack` | bool | 玩家是否在赛道上 | | `IsInGarage` | bool | 是否在车库 | | `IsDiskLoggingEnabled` | bool | 磁盘遥测是否开启 | | `IsDiskLoggingActive` | bool | 是否正在录制 .ibt | ### 👥 车手变更(Team Racing) | 变量名 | 类型 | 说明 | |---|---|---| | `DCLapStatus` | int | Driver Change 圈数状态 | | `DCDriversSoFar` | int | 已驾驶过的车手数 | ### 📷 摄像机 | 变量名 | 类型 | 说明 | |---|---|---| | `CamCarIdx` | int | 当前焦点车辆索引 | | `CamCameraNumber` | int | 当前摄像机编号 | | `CamGroupNumber` | int | 当前摄像机组编号 | | `CamCameraState` | bitfield | 摄像机状态位字段 | --- ## 六、重要枚举汇总 ### SessionState | 值 | 状态 | |---|---| | 0 | StateInvalid | | 1 | StateGetInCar(上车中) | | 2 | StateWarmup(暖胎圈) | | 3 | StateParadeLaps(编队圈) | | 4 | **StateRacing**(正赛中) | | 5 | StateCheckered(方格旗) | | 6 | StateCoolDown(冷却圈) | ### TrkLoc(赛道位置) | 值 | 含义 | |---|---| | -1 | NotInWorld | | 0 | OffTrack | | 1 | InPitStall(维修区) | | 2 | AproachingPits | | 3 | OnTrack | ### TrkSurf(路面材质) | 值 | 材质 | |---|---| | 0 | Undefined | | 1-4 | Asphalt | | 5-6 | Concrete | | 7-8 | Racing Dirt | | 9-10 | Paint | | 11-14 | Rumble Strip(路肩) | | 15-18 | Grass | | 19-22 | Dirt | | 23 | Sand | | 24-25 | Gravel | | 26 | Grasscrete | | 27 | Astroturf | ### TrackWetness(赛道湿度) | 值 | 级别 | |---|---| | 0 | Unknown | | 1 | Dry | | 2 | Mostly Dry | | 3 | Very Lightly Wet | | 4 | Lightly Wet | | 5 | Moderately Wet | | 6 | Very Wet | | 7 | Extremely Wet | ### PaceMode | 值 | 模式 | |---|---| | 0 | Single File Start | | 1 | Double File Start | | 2 | Single File Restart | | 3 | Double File Restart | | 4 | Not Pacing | ### CarLeftRight | 值 | 含义 | |---|---| | 0 | Off | | 1 | Clear(两侧无车) | | 2 | Car Left | | 3 | Car Right | | 4 | Cars on Both Sides | | 5 | 2 Cars Left | | 6 | 2 Cars Right | --- ## 七、SDK 客户端 API(C 语言接口) ```c // 初始化 / 关闭 bool irsdk_startup(); void irsdk_shutdown(); // 连接检测 bool irsdk_isConnected(); // 获取头部 const irsdk_header* irsdk_getHeader(); // 等待新数据并复制到本地缓冲区(推荐方式) bool irsdk_waitForDataReady(int timeOut, char *data); // 获取会话 YAML 字符串 const char* irsdk_getSessionInfoStr(); int irsdk_getSessionInfoStrUpdate(); // 检测会话信息更新 // 获取变量头 const irsdk_varHeader* irsdk_getVarHeaderPtr(); const irsdk_varHeader* irsdk_getVarHeaderEntry(int index); // 按名称查找变量 int irsdk_varNameToIndex(const char *name); int irsdk_varNameToOffset(const char *name); // 获取指定缓冲区的数据 const char* irsdk_getData(int index); ``` --- ## 八、Broadcast Messages(远程控制) 通过 Windows 消息 `IRSDK_BROADCASTMSG` 发送控制命令: ### 摄像机控制 ```c // 切换摄像机:按位置 irsdk_broadcastMsg(irsdk_BroadcastCamSwitchPos, carPosition, group, camera); // 切换摄像机:按车号 irsdk_broadcastMsg(irsdk_BroadcastCamSwitchNum, driverNum, group, camera); // 设置摄像机状态 irsdk_broadcastMsg(irsdk_BroadcastCamSetState, irsdk_CameraState, 0, 0); ``` ### 回放控制 ```c // 设置播放速度 irsdk_broadcastMsg(irsdk_BroadcastReplaySetPlaySpeed, speed, slowMotion, 0); // 跳转位置 irsdk_broadcastMsg(irskd_BroadcastReplaySetPlayPosition, irsdk_RpyPos_Begin, frameHigh, frameLow); // 搜索事件 irsdk_broadcastMsg(irsdk_BroadcastReplaySearch, irsdk_RpySrch_NextLap, 0, 0); // 搜索会话时间 irsdk_broadcastMsg(irsdk_BroadcastReplaySearchSessionTime, sessionNum, sessionTimeMS_high, sessionTimeMS_low); ``` ### 进站控制 ```c // 清空所有勾选 irsdk_broadcastMsg(irsdk_BroadcastPitCommand, irsdk_PitCommand_Clear, 0); // 加油(0 = 使用默认值) irsdk_broadcastMsg(irsdk_BroadcastPitCommand, irsdk_PitCommand_Fuel, addLiters); // 换左前胎(指定胎压 kPa,0 = 默认) irsdk_broadcastMsg(irsdk_BroadcastPitCommand, irsdk_PitCommand_LF, pressureKpa); // 换胎配方 irsdk_broadcastMsg(irsdk_BroadcastPitCommand, irsdk_PitCommand_TC, compound); // 快速维修 irsdk_broadcastMsg(irsdk_BroadcastPitCommand, irsdk_PitCommand_FR, 0); ``` ### 遥测录制控制 ```c irsdk_broadcastMsg(irsdk_BroadcastTelemCommand, irsdk_TelemCommand_Start, 0, 0); irsdk_broadcastMsg(irsdk_BroadcastTelemCommand, irsdk_TelemCommand_Stop, 0, 0); irsdk_broadcastMsg(irsdk_BroadcastTelemCommand, irsdk_TelemCommand_Restart, 0, 0); ``` ### 聊天宏 ```c irsdk_broadcastMsg(irsdk_BroadcastChatComand, irsdk_ChatCommand_Macro, macroNum, 0); ``` --- ## 九、与 F1 24 / ACC 的对比 | 特性 | iRacing | F1 24 | ACC | |---|---|---|---| | **协议** | 共享内存 | UDP | UDP + 共享内存 | | **更新频率** | 60Hz(可 360Hz) | 最高 60Hz | 物理步进 | | **多车数据** | ✅ CarIdx 数组(≤64 辆车) | ✅ 22 辆车 | ✅ Broadcasting | | **回放数据** | ✅ .ibt 文件 | ❌ | ❌ | | **远程控制** | ✅ Broadcast Msg | ❌ | ✅ Camera/Focus | | **写入支持** | ✅ 进站/摄像机/遥测 | ❌ | ✅ Camera/HUD | | **变量动态性** | 每车/每会话不同 | 固定结构 | 固定结构 | | **子 Tick 精度** | ✅ `_ST` 后缀变量 | ❌ | ❌ | | **运动平台** | ✅ 完整扭矩/加速度 | ✅ Motion Ex | ✅ Shared Memory | --- ## 十、关键注意事项 1. **变量动态性**:iRacing 的变量列表不是固定的—不同车辆/会话中可能不同,必须先读取 `varHeader` 来确定可用的变量和偏移量 2. **只读**:所有遥测数据只读,不能通过 SDK 修改车辆参数(只能通过 Broadcast Message 控制进站选项) 3. **三缓冲**:务必在 `irsdk_waitForDataReady()` 返回后立即拷贝数据,不要直接引用共享内存 4. **Session Info 更新**:通过 `sessionInfoUpdate` 计数器检测 YAML 字符串是否变化 5. **.ibt 兼容**:磁盘遥测文件结构与 Live 相同,可用相同代码解析(多了 `irsdk_diskSubHeader`) 6. **启动时序**:先调用 `irsdk_startup()` → 等待 `irsdk_isConnected()` → 等待 `SessionState >= StateRacing` 7. **360Hz 模式**:部分车辆支持 360Hz 遥测,检查 `tickRate` 字段