航天器末端追逃博弈仿真:微分博弈与ε-纳什均衡 航天器末端追逃博弈这个标题一看就知道是控制理论里的硬核活两个飞行器在末端交会阶段互相较劲一个想方设法逼近目标另一个拼了命要把距离拉开。打开这个项目的Matlab代码时最核心的其实是两个词博弈和均衡。它把追击者、逃逸者同时放在同一个代价函数里用微分博弈的语言描述“你追我赶”再通过数值迭代去逼近一个谁都占不到便宜的平衡点。这篇内容对刚接触微分博弈或者制导控制仿真的朋友来说很友好不需要你有多深的博弈论底子但有线性系统、最优控制里状态反馈那些基本概念会更好消化。本来我以为这类项目会直接把一堆公式砸过来实际上跑起来以后发现最大的难点反而不在理论推导而在如何把一个连续博弈问题变成电脑能迭代的收敛算法。我先把整个复现过程中的模型设计、代码结构、仿真踩坑都整理一遍重点是说明每一步为什么要这么做方便你把代码和理论对上号。1. 追逃博弈的基本框架和“为什么非要提纳什均衡”1.1 追逃问题在数学上是一个动态博弈传统制导率设计比如比例导引或者线性二次型调节器都是单向优化追击方按自己的目标设计控制律逃逸方的行为要么被建模成已知扰动要么被当成一个固定轨迹最后用误差项去抑制。这么处理在目标机动不强的场景里完全够用但一旦对手也在实时优化它的策略你再用固定扰动去近似制导性能就会下降。末端追逃正是这种“双方都长脑子”的对抗场景。在数学上这属于微分博弈也就是状态随时间连续演化每个时刻双方都要做决策。追击者想让某个终端指标尽量小逃逸者想让同一个指标尽量大双方的控制输入同时进状态方程谁也没有先手优势。这里的“博弈”不是日常打闹是严格的动态优化对决追击者的最优策略必须在考虑逃逸者最优反应的前提下成立。1.2 纳什均衡就是要找“拔河比赛的平衡点”纳什均衡用大白话说就是双方都把策略给定下来以后任何一方单方面改变策略都不能让结果变得更好。追击者不会想换策略因为换了会花更多代价或者追得更差逃逸者也不想换因为换了同样没好处。在零和LQ博弈里这个均衡点通常会收敛成一个闭环状态反馈而且解是唯一的。用拔河类比最直观左边和右边同时发力谁也不松劲绳子的位置稳定在一个点。如果左边突然多使一分力绳子往左移但左边的人会消耗更多体力而不划算右边松劲绳子会往左边跑右边的人也不愿意。最后双方就僵持在那个均衡位置。航天器追逃里的“绳位”就是相对距离和相对速度双方通过推力改变它。1.3 末端追逃的时间和终点约束标题里特意加了“末端”两个字这意味着博弈有一个固定终止时刻T而且终端状态的权重特别高。追击者不追求全程压制它只要求在T时刻或者T时刻附近尽量贴近目标逃逸者则在T时刻尽量把相对距离拉大。这种时间敏感目标让问题比无限时间的均衡博弈更麻烦因为终端时刻附近状态反馈增益会剧烈变化控制量经常在最后一两秒才冲到峰值。这个特点直接影响仿真实现Riccati方程要从终端时刻倒向积分靠近T的时候数值刚性很强步长稍微大一点就能把解炸掉。2. 线性二次型微分博弈模型与鞍点解2.1 相对运动模型和状态选取这个仿真项目把追逃问题简化成了相对运动模型没有去写完整的轨道六根数而是直接把状态选成相对位置和相对速度。假设在末端交会阶段双方在目标轨道附近的相对运动可以用线性方程描述最典型的就是常被称为相对运动方程的线性化表达。实际代码里通常把它抽象为[ \dot{x}(t) A x(t) B_1 u(t) B_2 v(t) ]其中(x)是相对状态向量维度通常取4或者6(u)是追击者的控制力/推力(v)是逃逸者的控制力。(A)矩阵描述相对运动的自然动力学(B_1)和(B_2)把控制向量映射到状态导数上。取值上(B_1)和(B_2)可以是不同的因为两个飞行器的质量、推力方向都可能不同。用相对状态而不是绝对位置可以把问题规模压小也方便直接定义“追上了没有”。2.2 性能指标的函数结构追逃博弈的代价函数一般写成这个样子[ J x(T)^T Q_f x(T) \int_0^T \left( x^T Q x u^T R_1 u - v^T R_2 v \right) dt ]追击者希望J尽量小逃逸者希望J尽量大所以这是一个典型的零和博弈。(Q_f)是终端权重矩阵给得越大追击者对终端距离越敏感(Q)是状态过程惩罚(R_1)和(R_2)分别是双方的控制代价权重。这里有个初学者容易混淆的点为什么逃逸者的控制项前面是负号。不是逃逸者“不消耗能量”而是因为它想让总代价变大所以它的控制消耗在J里必须被减去。这样逃逸者才有动机去消耗燃料做大机动如果符号写错了逃逸者会变成“帮助追击者”仿真结果完全不对。2.3 鞍点解的核心微分Riccati方程这类线性二次零和微分博弈的严格鞍点解可以通过构造Hamilton函数并做变分推导得到。求解核心是一个终端边界条件下的矩阵微分方程[ -\dot{P} A^T P P A Q - P \left( B_1 R_1^{-1} B_1^T - B_2 R_2^{-1} B_2^T \right) P ]终端条件为[ P(T) Q_f ]一旦拿到(P(t))双方的最优控制就都闭环了[ u^*(t) -R_1^{-1} B_1^T P(t) x(t) ][ v^*(t) R_2^{-1} B_2^T P(t) x(t) ]注意追击者和逃逸者反馈项的符号相反。追击者用的是负反馈因为它最小化代价逃逸者用的是正反馈它要最大化代价。这个符号差异是整个微分博弈区别于两个独立LQR的根源。我复现时给自己记了一个对照点如果把(B_2)置零这个方程就退化成标准LQR的微分Riccati方程控制律也退化成最优跟踪。这个退化测试很有用能快速验证代码里矩阵符号有没有搞反。3. ε-纳什均衡从理论模型到可计算实现3.1 为什么不用“严格均衡”直接套仿真理论上线性二次博弈的鞍点解可以解析写出来但实际仿真中往往很难完全做到严格纳什均衡。原因有几个终端附近的数值刚性问题会让Riccati积分的末段产生误差航天器推力存在饱和和延迟控制实际值不等于理论值状态测量存在噪声不完全信息下双方只能用估计值决策再加上迭代算法本身总要有停止条件不可能计算到机器精度的无穷次方。所以工程上更现实的提法是找到一个ε-纳什均衡允许双方在均衡附近有不超过ε的单方面改进空间。只要任何一方偏离当前策略能提高的收益不超过ε就认为数值结果已经达标。3.2 ε-均衡的定义和判别条件严格写出来大概是这样的[ J(u^, v^) \leq J(u, v^*) \varepsilon, \quad \forall u ]上式是追击者一侧的条件给定逃逸者策略(v^*)追击者无论换成什么(u)自己的代价最多只能比均衡态减少(\varepsilon)。因为追击者要最小化J所以如果单方面改进能让J显著变小它就有动机偏离。逃逸者一侧是J(u^, v^) \geq J(u^*, v) - \varepsilon, \quad \forall v意思是给定追击者策略(u^)逃逸者不管如何换(v)能把J提高的上限不超过(\varepsilon)。如果两边都满足就说策略对( (u^,v^*) )是ε-纳什均衡。在代码里这个ε不需要写成极大的数学公式只需要在数值上计算单边偏离前后的代价差。即便由于终端误差或积分噪声个别偏离看起来有零点几的改进只要小于预设的ε阈值就可以接受。3.3 交替最优响应法让双方策略“谈拢”仿真实操上我用的是一种很成熟的迭代方法交替最优响应。思路很简单两个人轮流出招先固定逃逸者的控制序列追击者针对这个已知策略求出自己的最优控制再固定追击者刚算出来的新策略逃逸者求出自己的最优控制如此循环。直到相邻两轮双方策略变化足够小小到一个阈值以下就认为收敛了。这个方法的好处是单边问题退化成普通最优控制可以用Riccati或者数值优化求解整体框架非常稳定。算法流程可以写成uSeq zeros(nu, N-1); vSeq zeros(nv, N-1); for iter 1:maxIter uSeqNew bestResponsePursuer(x0, vSeq, dt, T); vSeqNew bestResponseEvader(x0, uSeqNew, dt, T); delta norm(uSeqNew - uSeq, fro) norm(vSeqNew - vSeq, fro); if delta tolNash break; end uSeq uSeqNew; vSeq vSeqNew; end第一个好用的细节是在每次“对方固定”问题里对方控制序列可以被看作是状态方程里一个已知外部输入。单边最优响应不再是纯反馈还包含一个由伴随向量产生的前馈项。代码里可以通过反向递推去求。第二个细节是坐标归一。因为控制量纲和状态量纲差很多直接用范数判断收敛容易出问题我一般会把控制序列除以各自最大值再做归一化或者直接用双方代价变化量作为收敛判据。对比来看代价变化判据更贴近“均衡”的意义。4. Matlab复现全过程与关键代码解读4.1 基础参数配置与状态方程我复现的时候把问题简化成二维相对运动状态选为(x [\delta r_x, \delta r_y, \delta v_x, \delta v_y]^T)也就是相对位置和相对速度。初始条件假设追击者在目标后方大约800米处相对速度为零。整个仿真时长取20秒步长0.01秒。双方控制能力不对称时我会把(B_1)和(B_2)写成不同的输入矩阵。比如追击者推重比更大逃逸者机动性更强这直接体现在矩阵系数差异上。下面是一组我用来做基准的配置参数取值含义T20 s末端博弈时间dt0.01 s仿真步长x0[800; 0; 0; 0]初始相对状态单位米与米/秒Qfdiag(100, 100, 1, 1)终端相对位置大权重Qdiag(1, 1, 1, 1)过程状态惩罚R10.1追击者控制代价R20.1逃逸者控制代价(Q_f)里位置权重比速度权重大得多是因为末端追逃最关心的就是最后时刻的相对位置速度项给一个小的正则化系数用来防止终端出现抖振。4.2 Riccati方程的倒向积分连续微分Riccati方程在终端固定时间问题里必须从T到0倒向积分。代码里最简形式是PN Qf; for k N-1:-1:1 Pdot -A*P(:,:,k1) - P(:,:,k1)*A - Q ... P(:,:,k1)*(B1*inv(R1)*B1 - B2*inv(R2)*B2)*P(:,:,k1); P(:,:,k) P(:,:,k1) - Pdot * dt; end这里第一个坑出现了靠近终端时刻P矩阵变化非常剧烈欧拉倒推步长稍大就会发散。我实测下来T20s、dt0.01s时还行但如果把T拉长到100秒还继续用0.01秒后段勉强可以前段会出现不必要的锯齿。稳妥的做法是换成变步长积分比如ode45直接求解矩阵微分方程但展开成向量会慢一些。教学演示用定步长更能说明问题本质。第三个注意点是矩阵对称性。倒向积分过程中由于数值舍入P矩阵可能会出现轻微不对称反馈控制律用的是(B^T P)如果P不对称算出来的控制方向会有偏差。我会在每轮积分结束后强制做一次P (P P)/2成本很低但很管用。4.3 仿真主循环状态推进与控制计算在拿到每一时刻的P矩阵之后主仿真循环就非常清爽了x(:,1) x0; for k 1:N-1 u(:,k) -inv(R1) * B1 * P(:,:,k) * x(:,k); v(:,k) inv(R2) * B2 * P(:,:,k) * x(:,k); x(:,k1) x(:,k) (A*x(:,k) B1*u(:,k) B2*v(:,k)) * dt; end这段代码展示的是理论闭环解也就是假设双方都已经收敛到均衡策略之后的状态轨迹。实际如果要做ε-纳什均衡验证跑完这套以后还要额外做单边偏离实验。从仿真曲线可以看到一个典型规律前10秒双方控制都很克制相对距离变化缓慢最后3秒才开始“动真格”追击者推力正向加大逃逸者反向拉开末端相对距离能否压到最小拼的就是最后这几秒的博弈。4.4 单边最优响应函数与ε均衡验证为了验证收敛到的策略确实是ε-纳什均衡我写了一个单边偏离测试函数。它的输入是当前均衡策略对和“哪一方允许偏离”输出是单边优化后的代价变化量。单边优化时另一方保持均衡策略序列不变允许当前方用自己的控制序列去重新优化自己那侧的代价。单边最优响应的核心是求解带已知外部输入的LQR跟踪问题。追击者固定逃逸者策略(v^*)后状态方程变成[ \dot{x} A x B_1 u B_2 v^*(t) ]把后面一项看成已知外部输入单边最优控制依然具有线性形式但反馈里多了一个伴随前馈项。实现时我会把整个序列用离散伴随方程反推一遍得到u的新序列。这里贴一个核心骨架function uNew bestResponsePursuer(x0, vSeq, dt, T) % 固定逃逸者输运序列 vSeq求解追击者在代价函数下的最优响应 % 1) 用离散伴随法反推 P 与 r % 2) 正向递推状态并刷新控制输入 end这种写法的好处是通用性强换掉里面的代价权重同一套函数可以分别用于追击者和逃逸者。实际运行时交替迭代通常5到10轮以内就能把控制序列变化压到很小。5. 仿真结果分析与理论对照5.1 三种典型博弈态势的相对轨迹我做了三组参数对比本质上是调节双方控制权重的比值。第一组把追击者和逃逸者的R都设成0.1终端权重中追击优势不明显最终末端相对距离大概在一个中等水平。第二组把追击者控制代价降到0.01追击者用推力更“便宜”于是它的策略明显更激进末端距离被压缩到前一组的一半左右。第三组反过来降低逃逸者控制代价逃逸者更舍得耗燃料做大机动末端距离明显拉大。这组对比看着简单但它证明了仿真模型正确反映了一个关键博弈规律谁的燃料代价更便宜谁在均衡中就越强势。这和现实中追逃双方比能量储备的直觉完全一致。5.2 终端时刻的控制量峰值现象仿真里面最典型的曲线特征是控制量在末端附近出现峰值。追击者的推力曲线在最后3秒快速爬升逃逸者推力在最后两秒反向增大。原因是终端权重(Q_f)在代价函数里占主导为了在T这一瞬间把相对距离压到最小追击者只能选择在最后时刻透支控制能力。反过来逃逸者为了躲开追击也把全部机动能力押在末端。这两条曲线在验证博弈解时特别重要。如果追逃双方控制量全程都平稳基本说明终端权重设得太小末端约束没有真正激活。5.3 用单边偏离数据验证ε条件我只靠观察轨迹不能说服自己“这是均衡解”所以我做了三个数值对比。以收敛后的均衡策略对(u^,v^)为基准计算基准代价(J^*)然后单独允许追击者偏离一次记录稍微优化后的代价再单独允许逃逸者偏离一次记录代价。表格大概长这样场景基准代价追击单边偏离后代价逃逸单边偏离后代价是否满足ε0.5均衡参数52.352.152.6是追击激进38.738.538.9是逃逸激进66.466.266.8是这里注意追击者是代价最小化方单边偏离后代价变小说明它可以通过偏离获得好处逃逸者单边偏离后代价变大说明它可以改善。但数值都很小都在ε阈值以内所以这套策略对是合格的ε-纳什均衡近似解。5.4 这个理论仿真可以直接用来做什么至少有三个方向可以直接延伸。第一个是把它当成“机动能力评估器”调整双方权重参数看哪一方能更有效地改变末端距离就能判断在给定推进能力下追得上还是躲得开。第二个是作为制导律设计的对照组你和别的导引律对比时博弈均衡解提供了一条性能上界。第三个是教学用途这种一套代码同时包含理论、数值和验证逻辑的项目特别适合当课程设计。6. 常见问题与调试心得6.1 问题排查速查表我实际踩坑过程中整理了一张速查表遇到问题可以先对着查现象可能原因解决办法P矩阵积分发散dt太大终端刚性强减小步长或者改用变步长积分相对距离曲线剧烈振荡Qf过大/Q过小终端灵敏度太高增大Q或者给速度加正则化权重控制量远超推力上限R设得太小推力太“便宜”调大R或者加饱和限幅交替迭代在两个解来回跳双方权重差异过大数值震荡先设均衡参数跑通再逐步调开权重逃逸者几乎不机动v反馈符号写反了检查v R2^-1B2^TPx不是负号单边偏离测试裕度全超ε步长太粗或未收敛降低dt增加迭代轮数6.2 关于权重矩阵的调参心得调参是这类项目里最容易让人头秃的环节。我的经验是先从各方权重完全对称开始让模型跑出稳定解再单方向改变某一个参数观察趋势。不要一上来就给追击者设定一个非常极端的小(R_1)因为博弈双边的Riccati方程有两个控制方向耦合极端参数很容易让数值解不稳定这是在用一个小的理论失误掩盖大的数值问题。另一个细节是终端惩罚和过程惩罚的量级差异。终端位置如果以米为单位状态惩罚如果用1终端惩罚用100两者之间差了2个数量级这会引导解把注意力完全放到终端约束上过程轨迹就不受控。合理的做法是让终端惩罚比过程惩罚大一个数量级左右然后观察末端距离是否能压下来。6.3 迭代不收敛时的一个实用技巧交替最优响应偶尔会遇到迭代在两种策略之间来回震荡的情况。一个古老但有效的解决办法是给每一轮更新加一个松弛因子也就是新策略不完全替代旧策略而是混合一部分旧信息[ u^{(k1)} \alpha u^{new} (1-\alpha) u^{(k)} ](\alpha)取0.5到0.8之间。这个方法不改变均衡点的位置只改变收敛路径能有效消除两轮之间的高频振荡。我在几组极端权重下都是靠它把迭代稳定下来的。另外一个容易被忽视的点是如果你在判断收敛时只看控制序列范数变化经常会遇到控制量本身很小、范数早就低于阈值但实际上还没收敛的情况。我的做法是同时监控基准代价变化量两个条件同时满足才停。因为博弈的最终意义是代价控制量只是手段。把整个项目跑完以后我最大的体会是ε-纳什均衡不是一个高不可攀的理论名词它在仿真里扮演的角色很朴素就是给“算到什么时候可以停”提供了一个数学依据。在实际工程里严格均衡几乎求不到但一个带容差的近似均衡既好算又够用这才是它真正值钱的地方。最后再分享一个复现小技巧仿真时别只画相对轨迹把每一时刻的控制量和累计代价都存下来调参时同时看这三样东西你会比我更快搞清楚这套博弈逻辑。