Skip to content

其他事项-–-自定义 AI

汉化标题:其他事项-–-自定义 AI
原文标题:Other-Things-–-Custom-AI
汉化更新时间:2026-01-14 18:34:50 +08:00
英文原文最新更新时间:2025-09-26 13:46:06 -0300

在 0.1.78 版本之后,现在可以使用 AC 来尝试并开发自定义 AI。一个外部应用可以连接到由 CSP 创建的几个内存映射文件以获取所有车辆的当前状态,并可为全部或部分车辆填充新的输入状态。也有一些函数允许控制模拟的某些方面,例如禁用车辆间碰撞、减慢模拟速度、传送车辆或重启比赛。

整个功能目前还处于实验阶段,仅对在 “surfaces.ini” 中明确允许应用自定义 AI 的赛道有效。这只是一个临时措施,以确保在此阶段具有这些控制模拟的选项时不会破坏任何竞争性内容。

入门

要激活自定义 AI:

  • 打开 assettocorsa/extension/config/new_behaviour.ini,找到 CUSTOM_AI 节并将 ENABLED 设置为 1。这里还有其他选项可用于在需要时加快加载和整体性能(另外,确保整个 “New Behavior” 模块也已启用)。

  • 打开你想在其上使用自定义 AI 的赛道的 surfaces.ini激活扩展物理,然后在同一文件中添加 [_EXTRA_PERMISSIONS] ALLOW_CUSTOM_AI_MANIPULATION=1

第一步

开始时,想要控制某辆车的外部工具应创建一个名为 AcTools.CSP.NewBehaviour.CustomAI.CarControls<N>.v0 的新的内存映射文件(其中 <N> 是从 0 开始的车辆索引),其结构如下(开始时可全部填零或类似值):

cpp
struct cai_car_controls { 
  /* 所有结构按 4 字节对齐 */

  float gas;
  float brake;
  float clutch;
  float steer; /* 将转向值规范化到 -1 到 1 */
  float handbrake;

  bool gear_up; /* 单字节值,1 表示真,0 表示假 */
  bool gear_dn;
  bool drs;
  bool kers;

  bool brake_balance_up;
  bool brake_balance_dn;
  bool abs_up;
  bool abs_dn;

  bool tc_up;
  bool tc_dn;
  bool turbo_up;
  bool turbo_dn;

  bool engine_brake_up;
  bool engine_brake_dn;
  bool mguk_delivery_up;
  bool mguk_delivery_dn;

  bool mguk_recovery_up;
  bool mguk_recovery_dn;
  byte mguh_mode; /* 无符号字符 */
  bool headlights;

  byte teleport_to; /* 设为 1 以传送到维修区,设为 2 以传送到 `teleport_pos` */
  bool autoclutch_on_start;
  bool autoclutch_on_change;
  bool autoblip_active;

  float3 teleport_pos; /* 三个浮点数,总计 12 字节 */
  float3 teleport_dir; /* 注意:在 0.1.79 之前此项错误地被反转 */

  bool autoshift_active;
}

此文件可以在 Assetto Corsa 启动后创建,但一旦 CSP 发现它,它会快速用来自该文件的新车输入数据将该车辆的原始车辆控制器替换为自定义控制器。数据以 333 Hz 被读取,但可以不那么频繁地更新。当发生此情况时,CSP 还会创建一个名为 AcTools.CSP.NewBehaviour.CustomAI.Car<N>.v0 的新的内存映射文件。在该文件中,CSP 会以 cai_car_data 结构(其中包含四个 cai_wheel_data)的形式提供车辆状态的详细描述:

cpp
struct cai_car_data {
  int packet_id; /* 更新时递增 */
  float gas;
  float brake;
  float clutch;
  float steer; /* 以度为单位的转向角 */
  float handbrake;
  float fuel;
  int gear;
  float rpm;
  float speed_kmh;
  float3 velocity;
  float3 acc_g;  /* G 力(Z 为前向/后向加速度,X 为左右力) */
  float3 look;   /* 车辆朝向 */
  float3 up;
  float3 position;
  float3 local_velocity;
  float3 local_angular_velocity;
  float cg_height;
  float car_damage[5];
  cai_wheel_data wheels[4];
  float turbo_boost;
  float final_ff;
  float final_pure_ff;
  bool pit_limiter;
  bool abs_in_action;
  bool traction_control_in_action;
  uint lap_time_ms;
  uint best_lap_time_ms;
  float drivetrain_torque;
  float spline_position;      /* 在 AI 样条(fast_lane.ai)上的位置 */
  float collision_depth;      /* 当前碰撞深度(米) */
  uint collision_counter;     /* 碰撞时递增 */
  uint wheels_valid_surface;  /* 如果第 N 位被设置,则第 N 个车轮在有效赛道表面上;如果所有车轮都在有效表面,则为 15 (1|2|4|8);在 0.1.79 中添加。 */
}

struct cai_wheel_data {
  float3 position;
  float3 contact_point;
  float3 contact_normal;
  float3 look;      /* 车轮朝向 */
  float3 side;      /* 指向车轮侧向的向量 */
  float3 velocity;  /* 车轮在世界空间中的速度 */
  float slip_ratio;
  float load;
  float pressure;
  float angular_velocity;
  float wear;
  float dirty_level;
  float core_temperature;
  float camber_rad;
  float disc_temperature;
  float slip;
  float slip_angle_deg;
  float nd_slip;
};

总而言之,如果外部应用希望控制模拟中的第二辆车,它应当:

  • 创建一个新的内存映射文件 AcTools.CSP.NewBehaviour.CustomAI.CarControls1.v0,大小为 cai_car_controls 结构并用零填充(或者制动可使用 1);
  • 等待一会儿,让 CSP 创建 AcTools.CSP.NewBehaviour.CustomAI.Car1.v0
  • 如果找到该文件,打开它、映射它并开始循环读取车辆状态并输出其控制指令;
  • 如果未创建该文件,可能是因为未启用自定义 AI,或赛道不允许自定义 AI,或该车辆无法被控制(例如在线的远程车辆)。

其他车辆在哪里

在启用自定义 AI 的情况下,CSP 会以 60 Hz(或当前帧率)在 AcTools.CSP.NewBehaviour.CustomAI.CarPublic<N>.v0 文件中发布所有车辆的信息。该信息更为简化(主要是因为关于在线远程车辆的数据受限),但希望这对 AI 足够:

cpp
struct cai_car_public_data {
  int packet_id; /* 更新时递增 */
  float steer;
  float rpm;
  float spline_position;
  float speed_kmh;
  float3 velocity;
  float3 acc_g;
  float3 look;
  float3 up;
  float3 position;
  float car_damage[5];
  bool is_braking;
}

控制模拟

要控制模拟状态,请创建一个新的文件 AcTools.CSP.NewBehaviour.CustomAI.SimState.v0 并用下列结构填充它:

cpp
struct cai_sim_control {
  bool pause;               /* 设为 1 可暂停模拟 */
  bool restart_session;     /* 设为 1 可重启当前回合 */
  bool disable_collisions;  /* 设为 1 可禁用碰撞 */
  byte extra_sleep_ms;      /* 如果你的 AI 在开发时需要时间来得出答案,
                               此选项可减慢模拟 */
};

自 0.2.8 起,你还可以通过 AcTools.CSP.NewBehaviour.CustomAI.SimState.v1 来控制模拟时间(使用 “v1” 而不是 “v0” 以保持兼容):

cpp
struct cai_sim_control {
  bool pause;               /* 设为 1 可暂停模拟 */
  bool restart_session;     /* 设为 1 可重启当前回合 */
  bool disable_collisions;  /* 设为 1 可禁用碰撞 */
  byte extra_sleep_ms;      /* 如果你的 AI 在开发时需要时间来得出答案,
                               此选项可减慢模拟 */
  float time_scale;         /* 1 为正常模拟时间缩放,增大以加快时间流逝 */
};

绘制调试线

为调试目的,你也可以绘制一些调试线。为此,创建一个大小至少为 16 KB 的新文件 AcTools.CSP.NewBehaviour.CustomAI.DebugLines.v0,并将以下 cai_debug_lines 结构写入其中:

cpp
struct cai_debug_lines {
  int count;
  cai_debug_line lines[count];
}

struct cai_debug_line {
  float3 from;
  float3 to;
  uint color;
}

示例

这里有一个基本的 C# 程序,演示如何连接、设置一些输入、控制模拟状态并绘制调试线