从摇杆到舵面:AFSIM 人在回路控制指令体系解析

从摇杆到舵面:AFSIM 人在回路控制指令体系解析

给无人平台设计一条外部遥控链路,第一个要回答的问题不是用什么协议,而是指令应当注入哪一层:直接写给运动模型,还是交给一个「虚拟飞行员」。指令注入的层次决定通道的能力上限,约定的清晰程度决定生态的扩展成本 ------ AFSIM 的交互式分析应用 Warlock,为这一判断提供了一套完整注脚。本文基于对 Warlock 全部人控入口的源码级梳理(Joystick、P6DOF_Controller、Tuner、PlatformMovement 等插件及 warlock_core),还原其从输入设备到舵面的完整控制链路;关键结论均可追溯至具体文件与函数。这项梳理同时服务于一个具体的工程问题:本研究团队正在为 AFSIM 无头运行环境 mission 开发外部遥控通道插件 wsf_xio_bridge,Warlock 的人控体系正是其设计参照。

一、四条总体结论

全部源码证据收敛于四条判断。

其一,Warlock 的人控不走 XIO 协议。 对本地平台,控制链路是 GUI 线程 → warlock::SimCommand 队列 → 仿真线程直接调用飞行员管理器 API。XIO 核心协议中不存在任何操纵面、油门类的直接控制报文。

其二,操纵注入的正确入口是飞行员对象,而不是 mover 的直接控制接口。 Warlock 从不调用 WsfP6DOF_Mover::SetDirectControlInputs() 一类的低层通路,而是 pilot->TakeManualControl() 加 SetManualControlData():八个参数覆盖杆、舵、油门、减速板、扰流板、襟翼、起落架,由飞行员对象在控制增稳或直接联动模式下转化为舵面指令。

其三,飞行员模式是一等公民。 MANUAL、AUGMENTED、HARDWARE、GUIDANCE、SYNTHETIC 五种模式各有明确的激活接口;所谓「接管」与「释放」,本质是激活哪一种飞行员------释放平台时,Warlock 一律将飞行员切回 SYNTHETIC。

其四,武器、传感器与电子战不定义专用 C++ 指令。 这一类操作走平台脚本约定通道:摇杆按键触发场景作者实现的同名脚本,周期数据回传同样经由脚本完成。

二、控制链路:一条主链,两条旁路

Warlock 的全部人控指令,走的是同一条「GUI 生产、仿真消费」的命令队列。

主链分六段。

SDL 摇杆与键盘经 XML 设备映射进入 GUI 线程;Joystick 插件的 GuiUpdate() 在每个刷新周期读取轴值,组装成 ControlData 结构;命令经 AddSimCommand() 进入 UtConcurrentQueue 无锁队列,GUI 线程生产,仿真线程消费;仿真线程以 30 Hz ClockEvent 驱动,在 Write 相位执行 ProcessCommands();ControlCommand::Process() 按 P6DOF 或 SixDOF 分支取到活跃手动飞行员(JoystickSimCommands.cpp:37-364);最终以 TakeManualControl() 加 SetManualControlData() 完成注入,操纵量经控制增稳转化为舵面输出。接管动作本身是一个固定序列:EnableControls(true) → 关闭自驾 → TakeManualControl(),随每个仿真拍重复执行(JoystickSimCommands.cpp:67-76)。

任何控制动作之前都要过权限门控:HasPermissionToControlPlatform() 以「按队伍限制」与「按平台名单限制」两个开关做逻辑与,两者默认关闭,即默认全部平台可控;拒绝时弹窗告警。

两条旁路值得单独说明。脚本通道把武器击发、传感器开关这类操作包成 ScriptExecuteCommand,进入同一条命令队列;若目标平台被外部系统(XIO/DIS)占有,则转为 WsfXIO_ScriptExecutePkt 发往宿主端。本地 UI 通道则根本不进仿真回路:HUD 模式切换、目标指定十字线、视角摇移,全部在 GUI 侧处理。

三、操纵数据的语义

两类操纵量语义------绝对位置与增量积分------直接决定停发指令后平台的行为。

ControlData 九个字段在 GUI 侧与仿真侧的语义并不对称,几处细节直接影响遥控协议设计。

字段 GUI 侧取值 仿真侧语义
roll / pitch / rudder -1,1 绝对位置,右滚 / 拉杆 / 右舵为正
throttle 0,1,加力联动后 0,2 0 慢车,1 军推,2 全加力
减速板 ±1 方向量 按 Δt 积分,位置钳位 0,1
起落架 0 / 1 0 收上,1 放下锁定
配平 × 3 ±1 方向量 值 = 方向 × 按住时长(秒)

两个口径需要分清:ControlData 的九个字段中,三个配平通道经独立的 SetTrimManualControlData() 接口注入;而 SetManualControlData() 的八个参数里,扰流板与襟翼在当前版本恒为零(GUI 侧标注 FUTURE 未实现)。两套数字并不矛盾,只是覆盖面不同。

油门的 0,2 三段语义由 GUI 侧合成:afterburner 通道大于 0.01 且油门高于 0.99 时,油门值延伸至 1+afterburner。减速板与配平是增量积分语义------停止发送指令即停止变化;杆、舵、油门则是绝对位置语义------停止发送时保持最后位置。这两类语义决定了停发指令之后平台的行为,遥控通道必须分别对待。

Warlock 自身没有「100 ms 无输入自动归零」一类 failsafe,其安全性由三件事承担:无活跃手动飞行员时的回退链------硬件自驾保持姿态与速度,引导自驾保持高度与航向,合成飞行员不动作;减速板与配平的增量语义;以及释放平台时显式切回 SYNTHETIC 的规定动作。

CAS 是 manual pilot 的一种形态而非独立模式:控制增稳激活时,附加滚转角速度上限 180 度每秒、俯仰过载上限 8 g 的包线约束。

四、武器、传感器与电子战:脚本约定通道

武器与传感器的全部操作面,Warlock 没有定义一个专用 C++ 指令。

摇杆按键按下时,插件在平台上下文里执行约定名称的脚本:trigger_fire 通道对应 TriggerPulled 与 TriggerReleased,weapon_release 对应 WeaponReleaseButtonPushed,master_arm 对应 MasterArmToggle,诸如此类。脚本由场景作者实现,机型相关的开火逻辑、主保险状态全部留在场景侧。

数据回传同样走脚本:20 Hz 周期查询雷达扫描数据、当前武器、箔条与红外弹余量,以及一个位包标志字------其中每一位都有明确含义:可射击、Break-X 告警、ECM 发射、被干扰、主保险、主警告,直接驱动 HUD 告警显示;1 Hz 查询备用油量。

这个约定把「平台无关的座舱交互框架」与「机型相关逻辑」解耦。外部遥控通道若要获得同等能力,复制这一模式即可:bridge 只转发脚本调用,场景提供同名脚本,无需在 C++ 层为每种武器建模。一个旁证是,Warlock 自身对外部系统(XIO/DIS)控制的平台,人控手段同样只剩远端脚本执行一条路------约定通用到什么程度,由此可见。

五、自动驾驶与平台运动指令

自驾目标值与平台运动指令,是摇杆通路之外的两个正交注入面。

Tuner 插件的 Commands 对话框向飞行员对象注入自驾目标值,覆盖高度、垂直速度、迎角、俯仰角、滚转、偏航、速度(CAS / TAS / Mach)等约二十项 SetAutopilot* 接口,本质是给自驾 PID 设定值;另提供遗传算法整定 PID 的 Auto Tune。它的执行路径与摇杆通路形成对照:不走命令队列,GUI 线程仅置待发标志,由仿真线程上 20 Hz 重调度的墙钟事件直接调用飞行员接口------两条通路,两种线程模型,Warlock 并未强求统一。

PlatformMovement 插件提供改高度、转航向、到位置、到速度、跟航线、回航线、延时返航等运动指令,全部值经单位转换后入队。关键在于:其中六类动作对应七种 WsfXIO_ReRoutePlatformPkt 子命令------仅「到位置」一类就细分直接置位(cSET_LOCATION)与机动前往(cGO_TO_LOCATION)两种报文------这组报文就是 Warlock 对外控平台的全部运动指令面,语义可直接被遥控通道复用;改航线与延时返航两类则仅限本地平台。另一个值得警惕的细节:停靠窗路径的每条命令都有权限与外控检查,而 H / G 快捷键路径仅要求平台已选中,未做权限检查------同一功能的两条入口,约束并不对称。

六、对外部遥控通道设计的启示

对 wsf_xio_bridge 而言,Warlock 的价值在于提供了一个行为完全可知的参照系。

以 Warlock 为参照,wsf_xio_bridge 的差距与改进方向都相当具体。目前 bridge 走 mover 直控通路:SetDirectControlInputs() 四通道绝对值,绕过飞行员对象,无 CAS、无配平、无保持语义,唯一防线是 100 ms 无输入归零的 failsafe。油门 0,2 语义与 Warlock 一致,这一点无需改动。

按性价比排序,有三条演进路径。

其一,接管与注入改走飞行员对象:激活 Manual pilot,注入 SetManualControlData(),释放改 MakeSyntheticPilotActive(),行为即与 Warlock 完全一致,且天然获得 CAS 与自驾保持语义;现有直控通路可保留为降级模式。

其二,协议补齐八通道:新增减速板、起落架、配平字段,服务端按 Δt 积分------注意 Warlock 用静态变量计算 Δt 是跨实例共享的实现怪点,bridge 应改用成员变量;回退链引入后,归零 failsafe 降为最后防线。

其三,新增 xio_execute_script 命令映射 WsfPlatform::ExecuteScript(),一次性复用 Warlock 整套武器传感器脚本约定。

权限与留痕同样值得跟进:Warlock 的两级名单门控与 SimulationUserAction 全量留痕(写入 Mystic 事件管道)是人控系统审计的基本配置,无头部署场景下可退化为日志输出。

结语

Warlock 用一条「命令队列 + 飞行员对象」的主链,把全部人控入口收拢到同一注入层次;又用脚本约定,把机型差异留在场景侧。层次给出能力上限,约定给出扩展成本------对正在设计外部遥控通道的工程团队而言,先选定注入层次,再定义脚本约定,接口细节反而是最不难的部分。

相关推荐
Respect@17 天前
WSF_COMM_ROUTER
afsim
灵境(虚幻知音)1 个月前
Cesium动态轨迹性能瓶颈深度拆解:翼带与尾迹的底层优化实践
性能优化·cesium·3d引擎·afsim·翼带·尾迹·自定义着色器
thesky1234561 个月前
智能体面试准备(六十三):智能体人在回路(HITL)与审批流工程——中断、审批、回滚与可审计闭环
智能体·回滚·审批流·hitl·人在回路·中断续跑·可审计
vanillazheng1 个月前
三、状态机评估流程 & 任务分配执行
afsim
雨田哥2 个月前
我使用AFSIM助手写了一个想定场景脚本
ai·afsim·ai afsim·afsim助手·afsim智能助手·afsim智能编码·afsim智能问答
vanillazheng2 个月前
一、AFSIM概述
afsim
二DUAN帝6 个月前
态势仿真推演系统 AFSIM+UE 架构选型
qt·ue5·afsim
雨田哥6 个月前
Qt AFSim雷达态势显控终端-AI战术辅助智能体
ai·afsim·qt仿真·仿真智能体·战术辅助智能体·ai仿真智能体·雷达态势显控终端
Ma04071310 个月前
【论文阅读21】-基于大语言模型与领域知识图谱集成的CNC智能故障诊断
llm·知识图谱·故障诊断·cnc·rag·人在回路