有限时域线性二次调节器¶
背景¶
线性二次调节器(LQR)用于权衡状态调节误差与控制消耗。它是少数具有 完整连续时间参考解的最优控制问题之一,因此不仅能演示优化器成功 终止,还能用来检验数值转录的实际精度。
这个标量问题同时包含运行代价、自由终端状态和终端惩罚。文中将 Pockit 配点解与独立积分得到的 Riccati 解逐点比较。
问题定义¶
线性动力学为
目标是最小化
本例参数为
终端状态 \(x(T)\) 是自由变量。问题没有状态或控制边界;正权重 \(Q\)、\(R\) 和 \(F\) 使标量问题关于控制严格凸。
Riccati 参考解¶
将最优值函数写为
对 Hamilton-Jacobi-Bellman 方程中的 \(u\) 求极小,可得
标量 Riccati 方程及终端条件为
反向积分 \(P\) 后,参考状态满足
相应初态下的精确最优值为
示例用高精度 solve_ivp 独立积分上述方程,不复用 Pockit 的配点
方程或 Ipopt 结果。
变量与单位¶
本基准问题无量纲。
| 符号 | 含义 | 数值或单位 |
|---|---|---|
| \(t\) | 归一化时间 | - |
| \(x\) | 标量调节误差 | - |
| \(u\) | 标量控制 | - |
| \(A,B\) | 动力学系数 | \(-1,1\) |
| \(Q,R\) | 运行状态和控制权重 | \(1,0.1\) |
| \(F\) | 终端状态权重 | \(1\) |
建模取舍与限制¶
实现采用固定区间 \([0,1]\) 上的单个 Lobatto 阶段,共八个网格区间,
每个区间六个点。系统级变量 x_final 表示自由终端状态,并与阶段
末端相连,从而在不固定终端值的情况下构造终端惩罚。
该模型刻意保持为标量、线性、无约束且无量纲。它用于验证目标函数 构造、自由终端状态和轨迹精度。带约束、非线性、随机或估计器耦合的 控制需要更丰富的模型,并且通常不再具有这里的闭式参考结构。
运行示例¶
无界面运行并保存图片:
示例遵循统一流程:
system, phase = build_problem()
guess = initial_guess(phase)
solution = solve_problem(system, guess)
plot_solution(solution)
验证结果¶
脚本在 2,001 个时刻重构配点状态和控制,并与独立积分的 Riccati 参考 解比较。
| 指标 | 验证值 |
|---|---|
| 目标函数 \(J\) | \(0.231913974452\) |
| 终端状态 \(x(1)\) | \(0.025836906771\) |
| 相对 Riccati 解的最大状态误差 | \(6.104\times10^{-9}\) |
| 相对 Riccati 解的最大控制误差 | \(1.303\times10^{-6}\) |
| 相对 \(\tfrac12P(0)x_0^2\) 的目标函数误差 | \(4.149\times10^{-14}\) |
终端状态很小,但并未被固定为零;其优化值反映了残余误差与控制代价 之间的既定权衡。数值目标与连续 Riccati 最优值几乎达到机器精度一致。

源代码¶
完整可运行示例见:
examples/linear_quadratic_regulator.py。