构建最优控制问题¶
简介¶
Pockit 将连续时间最优控制模型转录为有限维非线性规划。动力学、代价、
约束和端点都由 System 及其阶段提供的 SymPy 符号定义;Pockit 再据此
构造配点方程和稀疏导数。
本页通过一个有效的最短时间模型说明核心建模调用。完整的求解与验证流程见 快速开始;阶段连接、共享变量和状态重置的严格定义见 多阶段指南。
选择转录方法¶
Radau 和 Lobatto 使用相同的建模接口。一个模型只应导入其中一套 System,
不要用后一次导入覆盖前一次导入。
节点类型的选择方法见 Radau 与 Lobatto 插值。下面的 最短时间模型使用 Radau,因为最优加速度会在已知网格边界处跳变。
构建最小模型¶
下列代码定义一个双积分器。物体从距离目标一米处静止出发,加速度限制为 一米每二次方秒,终止时间自由:
from pockit.radau import System
system = System(0)
phase = system.new_phase(
["position", "velocity"],
["acceleration"],
)
position, velocity = phase.x
(acceleration,) = phase.u
phase.set_dynamics([velocity, acceleration])
phase.set_integral([1.0])
phase.set_phase_constraint(
[acceleration],
[-1.0],
[1.0],
True,
)
phase.set_boundary_condition(
[1.0, 0.0],
[0.0, 0.0],
0.0,
None,
)
phase.set_discretization([0.0, 0.5, 1.0], [6, 6])
system.set_phase([phase])
system.set_objective(phase.I[0])
System(0) 表示系统没有静态参数。System.new_phase() 会创建状态、控制和
时间符号,阶段内的所有表达式都必须使用这些符号。终止时间传入 None 后会
成为优化变量;常数 1 的积分就是阶段时长,因此最小化 phase.I[0] 等价于
最小化终止时间。
最后一个 True 将加速度约束标记为 bang-bang,供 Pockit 的间断检查使用;
该标记本身不能证明任意模型都具有 bang-bang 最优解。
阶段配置参考¶
把阶段加入系统之前,先完成阶段配置:
| 建模内容 | 方法 | 输入关系 |
|---|---|---|
| 状态导数 | Phase.set_dynamics |
按 Phase.x 顺序为每个状态提供一个表达式 |
| 运行积分项 | Phase.set_integral |
求解后通过 Phase.I 访问各积分 |
| 路径边界 | Phase.set_phase_constraint |
表达式、下界和上界列表必须等长 |
| 状态与时间端点 | Phase.set_boundary_condition |
None 表示自由,数值表示固定,静态参数表达式表示共享关系 |
| 网格与多项式点数 | Phase.set_discretization |
使用均匀计数,或归一化网格坐标及逐区间点数 |
阶段表达式可以使用 Phase.x、Phase.u、Phase.t 和 Phase.s。单边约束
可在开放的一侧使用 -numpy.inf 或 numpy.inf。单独的状态、控制、时间或
静态参数符号会转为变量边界;一般 SymPy 表达式则保留为代数路径约束。
静态参数与多个阶段¶
静态参数是不随时间变化的优化变量。构造系统时为其命名,随后即可在端点、 目标函数或跨阶段表达式中使用对应符号:
system = System(["event_time"])
(event_time,) = system.s
phase = system.new_phase(["position", "velocity"], ["acceleration"])
# 同一符号可以作为前一阶段的终点和后一阶段的起点。
phase.set_boundary_condition(
[1.0, 0.0],
[0.0, 0.0],
0.0,
event_time,
)
多阶段系统按照实际发生顺序接收各阶段:
system.set_phase([phase_0, phase_1])
system.set_objective(objective)
system.set_system_constraint(expressions, lower_bounds, upper_bounds)
最后一个片段中的名称表示已经配置好的阶段对象和 SymPy 表达式。 多阶段指南给出了完整数学模式,并链接到三个可运行应用。
修改已配置模型¶
set_* 调用需要对符号表达式求导并编译数值函数,因此可能耗时较长。在
notebook 中可将主要设置放在不同单元格,只重跑发生变化的关系。若阶段已通过
System.set_phase() 加入系统,修改该阶段后应调用 System.update(),刷新
系统层索引和导数。
配置完成后,还需要构造初值、求解非线性规划,并在配点之间验证重构轨迹。 优化器指南说明两种求解后端;误差检查与网格调整 介绍当前支持的检查与调整流程。