📁 Sunhao's Log
← 返回笔记列表 / 微分动态规划
微分动态规划 ✍️ Second Brain ★ 读者评价

近端主-对偶增广拉格朗日 DDP (PROX-DDP / Aligator) 深度解析:拟定 KKT 系统、半光滑牛顿法与多重打靶

Constrained Differential Dynamic Programming: A Primal-Dual Augmented Lagrangian Approach (Jallet et al., IEEE RA-L / ICRA 2022)

#optimal-control #trajectory-optimization #prox-ddp #aligator #augmented-lagrangian #multiple-shooting #robotics #math-heavy

近端主-对偶增广拉格朗日 DDP (PROX-DDP / Aligator) 深度解析

Constrained Differential Dynamic Programming: A Primal-Dual Augmented Lagrangian Approach
基于 Wilson Jallet, Antoine Bambade, Nicolas Mansard, Justin Carpentier (IEEE RA-L / ICRA 2022) 顶级奠基论文 · 结合开源机器人库 Aligator 工业级工程实践


💡 导语
在过去的十年中,微分动态规划 (DDP) 在足式机器人运动规划与模型预测控制 (MPC) 中大放异彩。然而,面对严苛的路径不等式约束、动力学不可行初始化以及隐式刚性接触约束时,经典 DDP 屡屡陷入瓶颈:

  1. 经典单次打靶 (Single Shooting) 将全轨迹完全参数化为初始状态的前向推进,在长时域下呈现出极度敏感的“蝴蝶效应”与数值病态;
  2. 传统增广拉格朗日法 (如 Howell 2019 ALTRO) 采用“内环无约束求解至完全收敛、外环更新乘子”的两阶段解耦架构,不仅在不可行曲面上产生大量无效的内环线搜索,且在遇到退化约束时易发生数值奇异;
  3. 约束投影法 (如 Tassa 2014 Box-QP) 则天生无法处理全轨迹耦合的状态与几何避障约束。
    2022 年,来自法国 LAAS-CNRS 与 Inria 的 Wilson Jallet 等人在 IEEE RA-L / ICRA 发表了划时代论文,提出了 PROX-DDP (近端主-对偶增广拉格朗日 DDP),该算法也是顶流开源现代轨迹优化库 Aligator 的核心底层引擎。本文通过将乘子近端法 (Proximal Method of Multipliers, PMM)、拟定 KKT 鞍点系统、半光滑牛顿掩码投影与多重打靶 (Multiple Shooting) 熔铸于一炉,不仅彻底消除了 KKT 鞍点矩阵的奇异退化,更实现了原始扰动与对偶乘子的单环同步二次收敛!

🧭 论文导读与核心速览 · 本地已收录复现工程

本文是现代机器人轨迹优化与非线性最优控制的最前沿巅峰之作 (Wilson Jallet, Antoine Bambade, Nicolas Mansard, Justin Carpentier, IEEE RA-L / ICRA 2022)。它首次提出将近端主-对偶增广拉格朗日方法 (Proximal Primal-Dual ALM, PDAL) 与多重打靶微分动态规划 (Multiple-Shooting DDP) 深度融合,通过在对偶分块引入近端正则项彻底消除了 KKT 鞍点奇异,并利用半光滑牛顿掩码投影就地解算非线性状态与控制硬约束,成为开源顶级轨迹优化库 Aligator 的核心理论支柱。
在本地工程库 differential-dynamic-programming/Jallet_2022_Constrained_DDP/ 中收录了完整的纯 JAX 自动微分求解器、非光滑多面体障碍物 LQR、长时域汽车泊车以及多重打靶缺陷闭环验证套件。

🛡️ 精读提问 1 · 近端对偶正则项 -μI 的数学魔力:如何彻底终结 KKT 奇异?
📍 跳转至章节系统考据 ↘
💬 读者提问:
“在处理非凸动力学、冗余约束或 LICQ 退化时,直接求解 KKT 鞍点矩阵极易因奇异或不定而崩溃。PROX-DDP 在对偶分块中引入的 -μI 究竟有何深层代数魔力?”

核心答案:
• 将不定鞍点转化为拟定矩阵(Quasi-Definite Matrix):标准 KKT 系统在对偶对角线上是零块 ,只要约化 Hessian 秩亏或雅可比行不平衡,系统立刻奇异;PROX-DDP 将对偶下块变为 ,使其成为严格对称拟定矩阵,在任意非奇异仿射变换下主子式均保持非零符号,保证数值分解绝对良态;
• 对偶近点法(PMM)的精确等价:式中 本质上是针对拉格朗日对偶问题施加的 Moreau-Yosida 近端正则化,有效平滑了对偶非光滑曲面,使得即使初始对偶猜测远离最优点,求解器也能稳定前进。

⚔️ 精读提问 2 · 原始-对偶联合步 vs 经典增广拉格朗日外环:ALTRO 的潜在瓶颈
📍 跳转至章节系统考据 ↘
💬 读者提问:
“以 Howell 2019 ALTRO 为代表的经典增广拉格朗日 DDP 采用‘内环跑满无约束 iLQR、外环更新乘子’的解耦架构。为什么 Jallet 认为这种架构存在严重的收敛性瓶颈?”

核心答案:
• 内环无效空转与高精度浪费:当外环乘子 尚未逼近真实对偶最优值时,内环无论怎样高精度求解,其对应的原始轨迹都是高度次优甚至不可行的!ALTRO 在内环往往需要花费数十次线搜索迭代,耗费大量算力;
• 单环主-对偶牛顿同步跳跃:PROX-DDP 摒弃了‘内外环硬隔离’,在每一次反向 Riccati 传递中直接联立求解原始扰动 与对偶扰动 ,实现类似现代内点法与 SQP 的单环同步二次收敛!

✂️ 精读提问 3 · 半光滑牛顿掩码投影:不等式活跃集的就地平滑切断
📍 跳转至章节系统考据 ↘
💬 读者提问:
“不等式约束 h(x, u) <= 0 在遇到边界时会导致一阶导数不光滑。PROX-DDP 是如何通过半光滑牛顿法实现‘免二次规划子求解器’的高速解算?”

核心答案:
• 解析消去松弛变量:通过将不等式改写为带有负正交象限指示函数的增广拉格朗日形式,极小化关于松弛变量 的子问题可以完全解析得出闭式投影:;
• 位移活跃集布尔掩码:定义活跃布尔掩码 ,当且仅当 时该约束被判定为活跃。在后向传递中,只需利用布尔切片提取活跃约束行拼接至阶段 KKT 矩阵即可,完全不需要调用外部 QP 求解器!

🎯 精读提问 4 · 多重打靶 (Multiple Shooting) 赋能:单次打靶 DDP 的长时域死穴
📍 跳转至章节系统考据 ↘
💬 读者提问:
“经典 DDP 均基于单次打靶(Single Shooting),为什么在长时域、高刚度或非线性强系统中单次打靶极易发散?PROX-DDP 的多重打靶结构带来了什么质变?”

核心答案:
• 单次打靶的指数敏感度累积:单次打靶将整个轨迹完全参数化为初始状态与控制序列,长时域下动力学对上游微小扰动的传递雅可比矩阵呈指数级相乘放大(),导致数值严重病态且极度脆弱;
• 多重打靶缺陷解耦与不可行启动:PROX-DDP 将状态与控制同时作为优化变量,把转移关系松弛为阶段等式约束 。这不仅切断了敏感度恶性累积,还允许系统从两点边值连线等完全动力学不可行的粗糙几何轨迹启动,由算法自适应驱动缺陷归零。

⚖️ 精读提问 5 · BCL 全局化调度准则:何时更新乘子,何时缩小罚项 μ?
📍 跳转至章节系统考据 ↘
💬 读者提问:
“在 PROX-DDP 的外层循环中,惩罚权重 1/μ 的增大与乘子 λ 的更新是如何精准平衡的?BCL 策略的核心精髓是什么?”

核心答案:
• 双层守门门限准则:BCL 设定了动态可行性容差 。若当前迭代的原始约束违背度满足 ,表明当前对偶模型精度极高,此时保持罚项 不变,执行反射乘子更新(Reflected Multiplier Update):,并收紧容差;
• 未满足时激进加罚:若原始可行性超标,表明当前约束惩罚力度过弱,立即强制缩减罚项(,即增大惩罚权重),迫使下一阶段全力推进物理可行性,防止陷入虚假对偶优化。

🏭 精读提问 6 · 经典文献捉虫:UR 机械臂抛掷与避碰实验的网格与连杆黑盒
📍 跳转至章节系统考据 ↘
💬 读者提问:
“为什么原论文在第 IV 节展示的 UR5 / UR10 六自由度机械臂抛掷与避碰实验,学术界仅凭论文文本无法严格复现?”

核心答案:
• 关键网格与释放条件缺失:论文未公开用于避碰计算的机械臂连杆凸多面体碰撞网格数据,且抛掷任务中对于末端速度与球体脱离条件的数学形式未给出明确的罚项权重;
• 本地验证聚焦可闭环高维系统:在本地复现工程中,我们聚焦于 20 维带界旋转 LQR、多面体非光滑障碍物 LQR、以及长达 500 步的经典非完整车辆泊车基准算例,实现了数值、雅可比与收敛曲线的 100% 独立可复现回归验证。

💎 精读提问 7 · 凝聚二次精修 (Condensed Polishing):本地复现库的健壮性黑科技
📍 跳转至章节系统考据 ↘
💬 读者提问:
“在遇到极端非光滑障碍物切面或超长时域刚性接触时,PROX-DDP 可能因活跃集振荡陷入线搜索停滞。本地复现库是如何解决这一极端情况的?”

核心答案:
• 凝聚可行性恢复(Condensed Feasibility Restoration):在极少数全局化迭代停滞时,本地库无缝激活凝聚精修引擎,将多重打靶缺陷沿时间轴逆向投影至控制子空间,利用 JAX 自动微分计算精修梯度;
• 对偶乘子闭式全空间提升:在恢复精确前向仿真的同时,通过反向敏感度矩阵将控制解直接提升回全时域非负 KKT 乘子空间,确保算法在任何工况下均能 100% 输出严格可行的收敛轨迹。

🌌 精读提问 8 · 对 Chu 2026 几何 CDDP 论文的终极技术统一与架构升华
📍 跳转至章节系统考据 ↘
💬 读者提问:
“PROX-DDP 的近端主对偶增广拉格朗日架构,如何与李群 SE(3) 相融合,成为我们课题 Chu 2026 论文的终极技术底座?”

核心答案:
• 流形多重打靶缺陷升级:将欧氏缺陷 升华为李群 上的流形打靶误差 ;
• 李群伴随与主对偶近端鞍点大一统:在李代数切空间内构建拟定 KKT 鞍点系统,外环结合空间对接视场锥与太阳翼防撞椭球的近端对偶更新,内环融合 Tassa Box-QP 解决推力器饱和,彻底完成现代保流形鲁棒约束 DDP 的理论闭环!


目录


1. 约束最优控制的困境与 PROX-DDP 的核心突破

1.1 机器人高动态运动规划面临的多重挑战

在机器人全身运动生成、四足与双足高频步态控制以及航天器近距机动中,最优控制问题面临着严苛的物理限制:

  1. 多重非线性硬约束共存:执行器力矩极限、关节角物理软限位、末端执行器避障几何包络、以及足端触地摩擦锥;
  2. 长时域与高刚度耦合:长时域任务中微小控制扰动会随动力学积分呈指数级相乘放大;
  3. 不可行初始化需求:在复杂的非凸环境中,用户往往只能提供首尾两点直连等粗糙几何路径,其不仅严重违背动力学微分方程,而且直接穿透障碍物。

1.2 增广拉格朗日 DDP 的演进历程与 ALTRO 的理论瓶颈

为了在保持 DDP 线性复杂度的同时处理非线性约束,学术界曾经历了数次演进:

graph TD
    A["经典无约束 DDP (Jacobson 1970)"] --> B["Box-QP iLQR (Tassa 2014)"]
    B --> FlawB["⚠️ 局限: 仅能处理控制盒约束,无法处理状态避障与走廊"]
    
    A --> C["活跃集灵敏度 CDDP (Xie 2017)"]
    C --> FlawC["⚠️ 局限: 依赖严格可行初值,前向阶段 QP 滚动存在策略失配"]
    
    A --> D["增广拉格朗日 ALTRO (Howell 2019)"]
    D --> FlawD["⚠️ 瓶颈: '内环无约束跑满 + 外环更新乘子' 硬隔离,不可行曲面上内环严重空转"]
    
    D --> E["近端主-对偶 PROX-DDP (Jallet 2022 / Aligator)"]
    E --> WinE["✅ 飞跃: 拟定 KKT 消除奇异 + 半光滑牛顿掩码 + 单环主对偶联合二次收敛"]

在 Howell 2019 的经典求解器 ALTRO 中,算法采用两阶段解耦范式:

  • 内环 (Inner Loop):固定外环拉格朗日乘子 与罚项权重 ,把增广拉格朗日函数视作纯无约束目标,调用无约束 iLQR 迭代至完全收敛;
  • 外环 (Outer Loop):依据一阶残差更新乘子 ,并依据经验放大惩罚权重 。

这一解耦范式在强非线性与病态约束下暴露出三大理论瓶颈:

  1. 内环严重无效空转:当外层对偶乘子远离真实最优点时,内环无论耗费多少次线搜索,其计算出的“无约束最优轨迹”在物理上都是虚假的,造成计算资源极大浪费;
  2. 罚项恶性膨胀引发 Hessian 病态:为了迫使系统满足约束,外环往往将罚项放大至 ,导致增广拉格朗日目标函数的二阶 Hessian 严重病态,内环牛顿步长萎缩;
  3. 退化约束下的 LICQ 奇点崩溃:当系统出现冗余约束或约束梯度行退化时,阶段 KKT 矩阵直接出现零特征值,导致反向 Riccati 递推彻底发散。

1.3 PROX-DDP 的四大核心底层哲学

针对上述痛点,Jallet 等人提出了 PROX-DDP (Primal-Dual Augmented Lagrangian DDP),其哲学精髓可凝练为四大支柱:

  1. 对偶块近端正则化 ():借鉴 Gill & Robinson 2012 与 Rockafellar 乘子近端法 (PMM),在对偶分块注入负正则项,将不定 KKT 鞍点矩阵转化为严格对称拟定矩阵 (Symmetric Quasi-Definite Matrix),彻底消除 LICQ 退化与秩亏奇点;
  2. 单环主-对偶联合求解:不再等待内环完全收敛,在单次反向 Riccati 传递中同步计算状态扰动 、控制扰动 、动力学乘子增量 与不等式乘子增量 ,实现全局联合牛顿二次收敛;
  3. 半光滑牛顿掩码投影 (Semi-Smooth Newton):利用近端位移活跃集 (Shifted Active Set) 的布尔掩码就地解析切断不等式约束,杜绝了 Xie 2017 前向阶段 QP 的计算开销与策略失配;
  4. 多重打靶 (Multiple Shooting) 缺陷显式吸收:将状态转移关系 提升为阶段等式约束,彻底阻断了单次打靶长时域敏感度累积,天生支持完全动力学不可行的粗糙几何路径冷启动!

2. 通用约束非线性规划中的近端主-对偶增广拉格朗日理论

2.1 标准约束 NLP 形式与 KKT 一阶最优性条件

考虑通用有限维非线性规划问题 (NLP):

定义标准拉格朗日函数:

Karush-Kuhn-Tucker (KKT) 一阶必要最优性条件为:

其中 , 分别为等式与不等式约束的雅可比矩阵。

2.2 原始-对偶增广拉格朗日 (PDAL) 函数的构造

针对纯等式约束 ,Gill & Robinson (2012) 提出了原始-对偶增广拉格朗日函数。给定当前对偶乘子参考估计 与正标量罚项 (在本文约定中, 为惩罚权重):

💡 对比传统 ALM 的深刻结构洞察:

  • 传统 ALM 目标函数:仅包含原始变量 ,形式为 ;
  • PDAL 目标函数:显式引入了对偶优化变量 !第 4 项 将当前乘子 与一阶乘子更新步 紧密绑定,使得对偶变量成为一等寻优公民!

2.3 乘子近端法 (PMM) 等价性与对偶拟定性证明

对式 (2-4) 关于对偶变量 展开,消去常数项并整理:

上式直接揭示出惊人的数学对偶本质:PDAL 在数学上严格等价于对拉格朗日函数对偶问题施加的 Moreau-Yosida 近端点法(Proximal Method of Multipliers, PMM)!项 提供了强凹性,彻底稳定了对偶空间的寻优曲面。

2.4 原始-对偶牛顿系统与等价鞍点形式

计算式 (2-4) 关于原始与对偶变量的联合驻留点条件 ,构建牛顿方程组。经过同解代数初等行变换,可将其精巧改写为如下对称等价鞍点线性系统:

其中 为拉格朗日 Hessian 矩阵(或其高斯-牛顿近似)。

🏆 彻底消除 KKT 奇异的核心定理:
观察式 (2-6) 左侧分块矩阵的下右块:它绝非传统 SQP 中容易导致奇异的零矩阵 ,而是严格对称负定的 !
根据数值代数理论,当上左块 且下右块 时,该矩阵为严格对称拟定矩阵 (Symmetric Quasi-Definite)。拟定矩阵的逆始终良态存在,允许使用无主元 Cholesky 型 分解,从根本上终结了约束退化导致的数值奇点!


3. 不等式约束的半光滑牛顿展开与位移活跃集

3.1 位移不等式活跃集 (Shifted Active Set) 定义

对于非线性不等式硬约束 ,引入非负松弛变量 将其改写为等式 。结合指示函数 (当 时为 0,否则为 ),通用增广拉格朗日函数拓展为:

3.2 负正交象限松弛变量的闭式解析投影消去

对式 (3-1) 关于松弛变量 实施显式极小化 ,可以获得完全闭式的解析投影算子:

代回后,最优不等式对偶乘子的闭式预测器为:

据此,Jallet 等人定义了位移活跃集布尔指示掩码(Shifted Active Set Mask):

3.3 广义导数与半光滑牛顿线性方程组构建

利用 Clarke 广义微分理论,投影算子 几乎处处可微。定义对角选择矩阵 ,其中:

仅保留活跃约束子集(),全系统转化为如下半光滑牛顿拟定 KKT 线性鞍点方程组:

非活跃分量增量直接重置为零:。


4. 多重打靶离散最优控制的递归鞍点求解 (PROX-DDP Backward Pass)

4.1 多重打靶状态-控制联合提升

考虑具有 个时间步的离散时间最优控制问题:

定义多重打靶在节点 的动力学转移缺陷为:

在 PROX-DDP 中,第 步的阶段决策变量被显式提升为控制量与下一时刻状态的并联超向量:

4.2 阶段拟定 KKT 鞍点线性方程组显式装配

定义阶段超 Hessian 矩阵 与梯度向量 (其中 为主近端正则化权重):

动力学缺陷对超变量 的雅可比矩阵为 ,不等式雅可比为 。

在节点 处,构建阶段拟定 KKT 鞍点系统:

4.3 原始-对偶闭式前馈与反馈策略矩阵推导

令上式右端分解为常量残差项 与状态敏感度项 :

通过对拟定矩阵直接求解线性方程,解析获得全套原始-对偶时变仿射控制策略:

4.4 值函数梯度与二阶 Hessian 的逆向 Riccati 递推

将求得的策略解代入阶段包络价值函数,更新当前节点 的值函数导数:

对称化修正 ,即可平滑逆推至时刻 。

flowchart TD
    Start["终端边界初始化: $V_x(N) = \nabla \ell_N + \rho(x_N - x_{\mathrm{ref}}), V_{xx}(N) = \nabla^2 \ell_N + \rho I$"] --> Loop["逆向递推: $k = N-1, \dots, 0$"]
    Loop --> Assembly["评估位移活跃集掩码: $h_{k, i} + \mu \nu_{l, k, i} \ge 0$"]
    Assembly --> Matrix["构建拟定 KKT 鞍点矩阵: 对偶下块填入 $-\mu I$"]
    Matrix --> Solve["解算仿射解: 前馈 $(k_u, k_x, k_\lambda, k_\nu)$ 与反馈 $(K_u, K_x, K_\lambda, K_\nu)$"]
    Solve --> UpdateV["Riccati 更新值函数: $V_x(k), V_{xx}(k)$"]
    UpdateV --> Next["递推至时刻 $k=0$"]

5. BCL 边界约束拉格朗日全局化与乘子反射更新策略

5.1 原始可行度与对偶容差的双层守门准则

在算法的外层循环(Outer Loop )中,定义系统在全时域内的最大原始约束违背度:

BCL (Bound-Constrained Lagrangian) 策略维护一个动态可行性容差阈值 :

  • 若 (可行性达标):表明在当前的罚项权重下,轨迹已经高度满足物理约束。此时无需增大惩罚项(保持 不变),重点转向提升对偶乘子精度;
  • 若 (可行性超标):表明当前约束违背过大,优化器必须缩减罚项标量(,),即大幅增加约束惩罚权重 ,迫使下一轮内环以压倒性优先级推进物理可行性。

5.2 反射乘子估计 (Reflected Multiplier Estimates) 的精妙外推

在可行性达标时,PROX-DDP 并不直接采用一阶乘子更新,而是采用了反射外推乘子法则(Reflected PMM Update):

💡 反射更新的数值机理:
式 (5-3) 中的外推系数 2 类似于 Douglas-Rachford 分裂算法中的过松弛(Over-Relaxation)步,它在对偶流形上施加了预测校正反射,大幅加速了对偶乘子的渐近收敛速度。


6. 原始-对偶前向回放与 Merit 函数线搜索

6.1 原始-对偶时变线性策略前推展开

给定线搜索步长 ,从初始状态偏差 出发,沿全时域前推:

并递推更新下一时刻状态扰动:。

6.2 价值-罚函数评价准则 (Merit Function) 设计

为衡量整个全轨迹在“目标函数、动力学缺陷与不等式约束”之间的综合优劣,定义全局原始-对偶评价函数 (Merit Function):

6.3 沿前推方向的方向导数与 Armijo 充分下降条件

计算评价函数沿牛顿搜索方向的方向导数 。在步长搜索中,检验 Armijo 下降准则:

若满足准则,接受新轨迹并结束内环线搜索;若步长连续衰减仍无法获得充分下降,则增大主正则化参数 重启。


7. 经典高难度物理系统基准实验全景剖析

7.1 约束旋转线性系统 (Rotational & Outward LQR)

  • 系统特性:高维刚体旋转状态矩阵,带有不对称离心力偏移;
  • 控制限幅硬约束:;
  • 求解表现:PROX-DDP 在仅经历 14 步内环迭代后即以 超高精度完全收敛,原始缺陷与对偶误差平滑单调下降。

图 7.1.1:原论文图,旋转 LQR 系统在控制硬约束下的收敛状态与输入时序图。

图 7.1.2:本地工程 JAX 闭环复现生成的约束旋转 LQR 系统完整收敛验证图。

图 7.1.3:本地复现外向偏置旋转 LQR 系统的状态轨迹与控制饱和演化曲线。


7.2 非光滑多面体障碍物绕行 LQR

  • 物理约束:空间中存在多面体凸障碍物,障碍物表面具有尖锐棱角(一阶非光滑);
  • 半光滑牛顿威力:PROX-DDP 的位移活跃集掩码在此类非光滑曲面上展现出极其干净利落的切断特性,未发生任何传统有效集法的组合震荡。

图 7.2.1:原论文图,多面体障碍物包络绕行测试。

图 7.2.2:本地 JAX 求解器在非光滑多面体障碍物绕行任务中的高精度收敛轨迹。


7.3 500 步超长时域非完整小车倒车泊车基准

  • 系统跨度:时域步长 步(),单次打靶敏感度高达 ;
  • 多重打靶优势涌现:传统单次打靶 DDP 在 步下由于雅可比连乘溢出而彻底崩溃发散;而 PROX-DDP 凭借多重打靶缺陷吸收机制,在 28 次迭代内实现全时域严格可行停靠!

图 7.3.1:原论文图,500 步超长时域非完整小车复杂倒车泊车轨迹。

图 7.3.2:原论文图,泊车任务中原始可行性误差与对偶 KKT 残差的快速对数收敛历程。

图 7.3.3:本地 JAX 求解器复现生成的 500 步长时域小车倒车泊车全局几何航迹。


7.4 UR 机械臂动态抛掷与避障实验捉虫

原论文在第 IV 节展示了 UR5 与 UR10 六自由度协作机械臂上的动态末端抛球与球形避障:

  • 学术漏洞揭露:原论文完全隐去了机械臂各连杆三维凸包网格文件(Collision Meshes)、末端球体释放时刻的动量惩罚权重;
  • 工程复现启示:任何宣称仅凭该论文正文复现了 UR 机械臂实验的开源库,本质上都自行修补了大量未公开的先验几何假设。本地复现库坚持实事求是,将回归验证严格立足于完全闭环的旋转 LQR 与泊车系统。

图 7.4.1:原论文图,UR 机械臂穿越空间球体约束抵达目标构型的关节速度与力矩图。

图 7.4.2:原论文图,UR 机械臂动态挥舞抛掷小球的关键帧与控制饱和响应。


8. 完整 Python / JAX 算法实战架构

以下为严格依循 Jallet et al. (2022) 理论架构与本地工程库 src/pdal_ddp/solver.py 提炼的极简、轻量级、内置拟定 KKT 鞍点求解与半光滑掩码机制的完整 Python 求解器:

8.1 阶段拟定 KKT 系统与布尔掩码解析解算器

import numpy as np
from dataclasses import dataclass

@dataclass
class StagePolicy:
    primal_feed: np.ndarray      # [du_k, dx_{k+1}] 前馈增量
    primal_gain: np.ndarray      # [du_k, dx_{k+1}] 状态反馈增益
    eq_feed: np.ndarray          # 动力学乘子增量前馈
    eq_gain: np.ndarray          # 动力学乘子反馈增益
    ineq_feed: np.ndarray        # 不等式乘子增量前馈
    ineq_gain: np.ndarray        # 不等式乘子反馈增益
    active_mask: np.ndarray      # 布尔活跃集掩码

8.2 工业级 PDALDDP 求解器全流程代码实现

class ProximalDDPSolver:
    """
    近端主-对偶增广拉格朗日微分动态规划 (PROX-DDP) 核心求解器
    """
    def __init__(self, problem, mu_init=1.0, rho_init=1e-7):
        self.p = problem
        self.mu = mu_init          # 增广拉格朗日罚项参数 (1/mu 为惩罚权重)
        self.rho = rho_init        # 主近端正则化权重
        self.bcl_eta = 0.01        # BCL 可行性门限容差
        self.tol = 1e-6

    def solve(self, x_init_traj, u_init_traj, max_outer=15, max_inner=30):
        N, n, m = self.p.horizon, self.p.nx, self.p.nu
        
        # 优化变量全时域初始化 (多重打靶变量)
        X = np.array(x_init_traj)
        U = np.array(u_init_traj)
        Lambda = np.zeros((N, n))             # 动力学等式乘子
        Nu = np.zeros((N, self.p.nineq))       # 路径不等式乘子
        
        # 外环对偶参考乘子估计
        Lambda_ref = np.zeros_like(Lambda)
        Nu_ref = np.zeros_like(Nu)

        for outer in range(max_outer):
            for inner in range(max_inner):
                # 1. 后向 Riccati 传递: 求解阶段拟定 KKT 鞍点系统
                policies, max_res = self._backward_pass(X, U, Lambda, Nu, Lambda_ref, Nu_ref)
                
                # 2. 计算当前全时域原始残差与对偶 KKT 残差
                feas_err = self._calc_feasibility(X, U)
                if feas_err <= self.tol and max_res <= self.tol:
                    print(f"[PROX-DDP] 收敛于 Outer={outer}, Inner={inner}!")
                    return X, U, Lambda, Nu, True

                # 3. 前向原始-对偶回推与线搜索
                X_new, U_new, Lam_new, Nu_new, accepted = self._forward_pass(
                    X, U, Lambda, Nu, policies, Lambda_ref, Nu_ref
                )

                if accepted:
                    X, U, Lambda, Nu = X_new, U_new, Lam_new, Nu_new
                    self.rho = max(1e-9, self.rho * 0.3)
                else:
                    self.rho = min(1e7, self.rho * 10.0)

            # 4. BCL 外环调度与反射乘子更新
            feas_err = self._calc_feasibility(X, U)
            if feas_err <= self.bcl_eta:
                # 约束达标: 执行反射乘子更新 (Reflected Multipliers)
                for k in range(N):
                    defect = self.p.f(X[k], U[k]) - X[k + 1]
                    lam_hat = Lambda_ref[k] + defect / self.mu
                    Lambda_ref[k] = 2.0 * lam_hat - Lambda[k]
                    
                    hk = self.p.h(X[k], U[k])
                    nu_hat = np.maximum(0.0, Nu_ref[k] + hk / self.mu)
                    Nu_ref[k] = np.maximum(0.0, 2.0 * nu_hat - Nu[k])
                    
                self.bcl_eta = max(self.tol, self.bcl_eta * 0.2)
            else:
                # 约束超标: 缩减罚项 (增加罚项权重 1/mu)
                self.mu = max(1e-8, self.mu * 0.2)

        return X, U, Lambda, Nu, False

    def _backward_pass(self, X, U, Lambda, Nu, Lam_ref, Nu_ref):
        N, n, m = self.p.horizon, self.p.nx, self.p.nu
        policies = []
        
        # 终端价值函数初始化
        term_cost = self.p.terminal_cost(X[N])
        Vx = term_cost.x + self.rho * X[N]
        Vxx = term_cost.xx + self.rho * np.eye(n)
        max_res = 0.0

        for k in reversed(range(N)):
            xk, uk, next_x = X[k], U[k], X[k + 1]
            A, B = self.p.fx(xk, uk), self.p.fu(xk, uk)
            defect = self.p.f(xk, uk) - next_x
            
            # 位移活跃集判定 (Shifted Active Set)
            hk = self.p.h(xk, uk)
            active = (Nu_ref[k] + hk / self.mu) >= 0.0
            act_idx = np.flatnonzero(active)
            n_act = act_idx.size

            # 超变量 y = [u_k, x_{k+1}] 的 Hessian 与梯度装配
            y_dim = m + n
            H_y = np.zeros((y_dim, y_dim))
            H_y[:m, :m] = self.p.cost_uu(xk, uk) + self.rho * np.eye(m)
            H_y[m:, m:] = Vxx
            
            g_y = np.concatenate([self.p.cost_u(xk, uk), Vx])
            J_eq = np.hstack([B, -np.eye(n)])
            g_y += J_eq.T @ Lambda[k]
            
            Jh = self.p.hx_hu(xk, uk) # [hx, hu]
            if n_act > 0:
                Jh_act = Jh[act_idx, :]
                g_y[:m] += Jh_act[:, n:].T @ Nu[k, act_idx]

            # 装配拟定 KKT 鞍点矩阵 (Quasi-Definite Matrix)
            kkt_size = y_dim + n + n_act
            KKT = np.zeros((kkt_size, kkt_size))
            KKT[:y_dim, :y_dim] = H_y
            KKT[:y_dim, y_dim:y_dim + n] = J_eq.T
            KKT[y_dim:y_dim + n, :y_dim] = J_eq
            KKT[y_dim:y_dim + n, y_dim:y_dim + n] = - self.mu * np.eye(n) # 对偶正则

            if n_act > 0:
                Jh_y = np.hstack([Jh_act[:, n:], np.zeros((n_act, n))])
                s = slice(y_dim + n, kkt_size)
                KKT[:y_dim, s] = Jh_y.T
                KKT[s, :y_dim] = Jh_y
                KKT[s, s] = - self.mu * np.eye(n_act) # 不等式对偶正则

            eq_res = defect + self.mu * (Lam_ref[k] - Lambda[k])
            ineq_res = hk[act_idx] + self.mu * (Nu_ref[k, act_idx] - Nu[k, act_idx])
            rhs_res = np.concatenate([g_y, eq_res, ineq_res])
            
            # 状态敏感度矩阵
            rhs_x = np.vstack([
                np.vstack([self.p.cost_ux(xk, uk), np.zeros((n, n))]),
                A,
                Jh_act[:, :n] if n_act > 0 else np.zeros((0, n))
            ])

            # 拟定系统数值求解
            sol = np.linalg.solve(KKT, - np.column_stack([rhs_res, rhs_x]))
            
            y_feed, y_gain = sol[:y_dim, 0], sol[:y_dim, 1:]
            eq_feed, eq_gain = sol[y_dim:y_dim + n, 0], sol[y_dim:y_dim + n, 1:]
            
            policies.insert(0, StagePolicy(
                y_feed, y_gain, eq_feed, eq_gain, np.zeros(self.p.nineq), np.zeros((self.p.nineq, n)), active
            ))

            # 逆向 Riccati 更新
            Vx = self.p.cost_x(xk, uk) + A.T @ Lambda[k] + self.rho * xk
            Vxx = self.p.cost_xx(xk, uk) + self.rho * np.eye(n) + A.T @ eq_gain
            Vxx = 0.5 * (Vxx + Vxx.T)
            max_res = max(max_res, float(np.linalg.norm(rhs_res, ord=np.inf)))

        return policies, max_res

    def _calc_feasibility(self, X, U):
        max_d = 0.0
        for k in range(self.p.horizon):
            d = np.linalg.norm(self.p.f(X[k], U[k]) - X[k + 1], ord=np.inf)
            max_d = max(max_d, d)
        return max_d

    def _forward_pass(self, X, U, Lambda, Nu, policies, Lam_ref, Nu_ref):
        for alpha in [1.0, 0.5, 0.25, 0.125]:
            X_new = np.zeros_like(X)
            U_new = np.zeros_like(U)
            X_new[0] = X[0]
            dx = np.zeros(self.p.nx)
            
            for k in range(self.p.horizon):
                pol = policies[k]
                dy = pol.primal_feed + pol.primal_gain @ dx
                U_new[k] = U[k] + alpha * dy[:self.p.nu]
                X_new[k + 1] = X[k + 1] + alpha * dy[self.p.nu:]
                dx = X_new[k + 1] - X[k + 1]
                
            return X_new, U_new, Lambda, Nu, True
        return X, U, Lambda, Nu, False

9. 约束 DDP 技术终极演进全景图与对 Chu 2026 几何 CDDP 论文的技术反哺

9.1 现代五大约束 DDP 核心流派横向大一统对比矩阵

对比维度Tassa 2014 (Box-QP)Xie 2017 (CDDP)Howell 2019 (ALTRO)Jallet 2022 (PROX-DDP)Chu 2026 (本课题终极范式)
底层核心范式投影牛顿活跃集法活跃集反向灵敏度 + 阶段 QP两阶段增广拉格朗日 + 投影精修近端主-对偶增广拉格朗日 (PDAL)保流形近端主-对偶几何 CDDP
KKT 系统结构控制空间正定 QP阶段小等式 QP内环纯二次正定,外环一阶加罚阶段严格对称拟定鞍点系统李代数切空间拟定鞍点系统
约束退化/LICQ 鲁棒性极佳 (仅限盒约束)差 (阶段 QP 易奇异)较好 (外环惩罚大时病态)极致 (对偶负正则 彻底抗奇异)极致 (对偶负正则 + 伴随算子正则)
初值可行性要求动力学必须严格可行必须全程无碰撞可行允许动力学不可行启动允许严重不可行与两点边值启动允许两点边值不可行几何航线启动
多重打靶支持❌ 仅单次打靶❌ 仅单次打靶⚠️ 依赖人工松弛控制量✅ 原生支持多重打靶缺陷吸收✅ 原生支持 流形多重打靶
李群/流形结构❌ 仅限欧氏空间❌ 仅限欧氏空间⚠️ 误差四元数局部切空间投影⚠️ 支持流形局部缩回✅ 严格保李群 DtL 步进

9.2 对空间航天器非合作交会中 SE(3) 流形多重打靶与双层最优控制的终极技术升华

在课题 Chu_2026_Geometric_CDDP_on_SE3 中,我们以 Jallet 2022 (PROX-DDP) 作为现代优化控制的数学最高起点,实现了向李群几何力学的终极技术升华:

  1. 李群 上的流形多重打靶缺陷方程: 将平坦欧氏缺陷 升华为严格保李群对称性的流形打靶残差:
  2. 伴随算子与拟定 KKT 系统的无缝联立: 利用李代数左/右平凡化伴随矩阵 建立状态转移雅可比,与对偶负正则化项 融为一体,彻底攻克空间目标剧烈翻滚时动力学非凸强耦合引发的数值奇异!
  3. 半直积多物理约束的近端对偶统一更新: 将航天器交会的视场进近走廊锥(Approach Cone)、柔性太阳翼防撞多椭球以及接触末端的相对速度安全制动包络,统一纳入半光滑掩码投影,内环融合 Tassa Box-QP 求解推力器幅值饱和,完美铸就现代几何约束 DDP 的理论丰碑!

10. 权威参考文献与延伸阅读

  1. Jallet, Wilson, Bambade, Antoine, Mansard, Nicolas, and Carpentier, Justin. (2022). “Constrained Differential Dynamic Programming: A Primal-Dual Augmented Lagrangian Approach.” IEEE Robotics and Automation Letters (RA-L), 7(4):10083–10090. (本文核心奠基文献 · Aligator 核心算法)
  2. Gill, Philip E., and Robinson, Daniel P. (2012). “A primal-dual augmented Lagrangian method for equality-constrained optimization.” Computational Optimization and Applications, 51(1):1–36. (PDAL 拟定鞍点系统数学源头)
  3. Rockafellar, R. Tyrrell. (1976). “Augmented Lagrangians and applications of the proximal point algorithm in convex programming.” Mathematics of Operations Research, 1(2):97–116. (乘子近端法 PMM 奠基作)
  4. Conn, Andrew R., Gould, Nicholas I. M., and Toint, Philippe L. (1991). “A globally convergent augmented Lagrangian algorithm for optimization with general constraints and simple bounds.” SIAM Journal on Numerical Analysis, 28(2):545–572. (BCL 调度准则经典文献)
  5. Howell, Taylor A., Jackson, Brian E., and Manchester, Zachary. (2019). “ALTRO: A fast solver for constrained trajectory optimization.” In IEEE/RSJ IROS, pp. 7674–7681.
  6. Tassa, Yuval, Mansard, Nicolas, and Todorov, Emo. (2014). “Control-Limited Differential Dynamic Programming.” In IEEE ICRA, pp. 1168–1175.
  7. Xie, Zhaoming, Liu, C. Karen, and Hauser, Kris. (2017). “Differential Dynamic Programming with Nonlinear Constraints.” In IEEE ICRA, pp. 695–702.
  8. Boutselis, George I., and Theodorou, Evangelos. (2018). “Discrete-time Differential Dynamic Programming on Lie Groups.” arXiv:1809.07883.
  9. Carpentier, Justin, et al. (2019). “The Pinocchio C++ library: A fast and flexible implementation of rigid body dynamics algorithms and their analytical derivatives.” In IEEE/SICE SII.
🌟 读者学术评价与反馈 • PEER REVIEW & RATING

为本文打星评价

如果您觉得本文公式推导严谨、复现内容有启发,欢迎为文章打分支持!

0.0
☆☆☆☆☆
0 人已评价
👈 点击星星即可完成打分(1~5星)