跳转至

多阶段最优控制架构

何时使用多个阶段?

当一套动力学和约束覆盖一个连续时间区间时,单阶段已经足够。若物理 模型或事件结构发生变化,则应使用多个阶段,例如火箭分级、运行模式 或催化剂切换、限速不同的道路区段、接触事件和理想化状态重置。

多个阶段也可以隔离时间尺度差异很大的区域,但每个阶段边界都应具有 明确的物理或数值含义。光滑问题只因需要更细网格,并不必然需要拆分 阶段。

Pockit 系统、阶段、变量和函数之间的关系

系统与阶段对象

一个 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)

求解后应分别密集验证每个阶段,并检查每个事件的左右两侧。连续残差和 重置残差需要分开报告;求解器成功状态不能替代这些物理检查。