docs: add iRacing telemetry data format reference

This commit is contained in:
2026-07-27 18:46:01 +08:00
parent 5bb4a82ae0
commit 29d51ad59e
+752
View File
@@ -0,0 +1,752 @@
# 📡 iRacing Telemetry APIIRSDK)完整规范
## 一、概述
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 StringYAML 结构)
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=R0=N1~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` 字段