多阶段最优控制架构¶
何时使用多个阶段?¶
当一套动力学和约束覆盖一个连续时间区间时,单阶段已经足够。若物理 模型或事件结构发生变化,则应使用多个阶段,例如火箭分级、运行模式 或催化剂切换、限速不同的道路区段、接触事件和理想化状态重置。
多个阶段也可以隔离时间尺度差异很大的区域,但每个阶段边界都应具有 明确的物理或数值含义。光滑问题只因需要更细网格,并不必然需要拆分 阶段。

系统与阶段对象¶
一个 Pockit System 包含 \(n_p\) 个阶段和一组共享静态变量:
\[
\mathcal P=\{P^{(0)},P^{(1)},\ldots,P^{(n_p-1)}\},
\qquad
\boldsymbol s=(s_0,s_1,\ldots,s_{n_s-1})^{\mathsf T}.
\]
静态变量是优化变量,而不是随时间变化的历程。它们可以表示事件时刻、 共享边界值、设计参数或其他需要被多个阶段共同访问的量。
阶段 \(i\) 拥有独立的时间区间、状态、控制、动力学、路径约束和积分:
\[
t\in[t_0^{(i)},t_f^{(i)}],
\qquad
\boldsymbol x^{(i)}(t),
\qquad
\boldsymbol u^{(i)}(t).
\]
其连续时间关系写为
\[
\begin{aligned}
\dot{\boldsymbol x}^{(i)}
&=\boldsymbol f^{(i)}
\left(\boldsymbol x^{(i)},\boldsymbol u^{(i)},t,\boldsymbol s\right),\\
\boldsymbol I^{(i)}
&=\int_{t_0^{(i)}}^{t_f^{(i)}}
\boldsymbol g^{(i)}
\left(\boldsymbol x^{(i)},\boldsymbol u^{(i)},t,\boldsymbol s\right)
\,\mathrm dt,\\
\underline{\boldsymbol c}^{(i)}
&\le\boldsymbol c^{(i)}
\left(\boldsymbol x^{(i)},\boldsymbol u^{(i)},t,\boldsymbol s\right)
\le\overline{\boldsymbol c}^{(i)}.
\end{aligned}
\]
每个端点状态和端点时刻都可以固定、自由,或写成共享静态变量的函数。
目标函数与系统约束¶
系统层目标函数组合各阶段积分与共享变量:
\[
\min\ F\left(
\boldsymbol I^{(0)},\ldots,\boldsymbol I^{(n_p-1)},\boldsymbol s
\right).
\]
系统约束用于施加跨阶段代数关系:
\[
\underline{\boldsymbol l}
\le\boldsymbol L\left(
\boldsymbol I^{(0)},\ldots,\boldsymbol I^{(n_p-1)},\boldsymbol s
\right)
\le\overline{\boldsymbol l}.
\]
总预算、积分目标以及不能只由单个阶段端点表示的关系,都适合放在 系统约束中。
连接事件¶
考虑两个阶段在未知事件时刻 \(t_s\) 相接。把 \(t_s\) 设为共享变量, 并令
\[
t_f^{(0)}=t_s=t_0^{(1)}.
\]
若状态连续,则
\[
\boldsymbol x^{(1)}(t_s^+)=\boldsymbol x^{(0)}(t_s^-).
\]
若事件包含瞬时跳变,应改用重置映射:
\[
\boldsymbol x^{(1)}(t_s^+)
=\boldsymbol R\left(\boldsymbol x^{(0)}(t_s^-),\boldsymbol s\right).
\]
对物理上发生跳变的分量,不应错误地强制连续。两级火箭 保持高度和速度连续,同时施加离散质量重置;批式反应器 和电动车案例则展示了其他领域的 连续事件连接。
实现模式¶
system = System(number_of_static_variables)
phase_0 = system.new_phase(state_names_0, control_names_0)
phase_1 = system.new_phase(state_names_1, control_names_1)
# 分别配置两个阶段,再通过共享静态变量和系统方程连接端点。
system.set_phase([phase_0, phase_1])
system.set_system_constraint(expressions, lower_bounds, upper_bounds)
system.set_objective(objective)
求解后应分别密集验证每个阶段,并检查每个事件的左右两侧。连续残差和 重置残差需要分开报告;求解器成功状态不能替代这些物理检查。