求解具有初值和终值约束的耦合 ODE

计算科学 Python 边界条件
2021-12-09 03:29:30

我的问题的实质如下:我有一个包含两个 ODE 的系统。一个具有初始值约束,另一个具有最终值约束。这可以被认为是一个单一系统,其中一些变量具有初始值约束,而其他变量具有最终值约束。

以下是详细信息:

我正在尝试使用连续时间有限水平 LQR 控制器来驱动线性动力系统。我想继续使用 Python 生态系统。

系统形式为,服从x˙(t)=Ax(t)+Bu(t)x(0)=x0

LQR 解决方案生成矩阵,使得最优控制输入 u(t),与成线性关系,为K(t)x(t)u(t)=K(t)x(t)

其中K(t)=R1BTP(t)

是连续时间 Riccati 微分方程的解(注意这个是一个矩阵)P(t)P(t)

P˙(t)=ATP(t)P(t)A+P(t)BR1BTP(t)+Q服从P(tf)=Q

A , , , , , ,都给出了。Bx0QQfRtf

用英语:你有一些从状态开始的动态系统。LQR 控制器生成一个在时间之间使用的反馈矩阵(通常称为问题的时间范围)x00tftf

请注意,这两个 ODE 仅在一个方向上耦合——的解不依赖于因此,解决该问题的一种方法是反转 Riccati 方程,以便将终值问题转化为初值问题,并使用标准 ODE 积分器然后我可以使用这个数值解来找到这让我很担心,因为 x(t) 的数值 ODE 求解器不一定会在与 $P(t) 的数值解中的时间相同的时间对 ODE 进行采样。也许有一些聪明的方法来执行这一点。P(t)x(t)0tfx(t)

我预见的解决问题的另一种方法是一起解决系统,但我不知道如何处理初始值和最终值约束的混合。这些问题的计算量大吗?我可以用 SciPy / Python 做吗?

4个回答

我不同意其他答案。由于您在反向时间和正向时间问题之间只有单向耦合,因此按照您的第一个建议,按顺序解决它们会更有效率。您只需要一个可以在任何时间P(t)t[0,tf]

您可以通过在输出值之间进行插值来做到这一点。我建议您使用支持密集输出的 Runge-Kutta 方法。比如,scipy.integrate.ode.dopri5就是基于这样一种方法。因此,您应该能够指定非常精细的输出时间,而无需强制积分器采取非常小的步骤(假设它的 scipy 接口已正确实现)。

这被称为两点边值问题并且得到了很好的研究。

拍摄方法编程非常简单,但数值可能极不稳定。

解决这些问题的标准方法是使用多重射击方法并通过标准非线性求解器求解相应的非线性方程组。有关非线性方程组的求解器列表,请参见
http://www.mat.univie.ac.at/~neum/glopt/software_l.html#nonlin

您将时间规则网格上的状态(通常不需要非常精细的网格)作为变量,并将边界条件和将时间 t 变量映射到时间 t+h 变量的映射作为方程。这给出了与变量一样多的方程。您只需要提供用于评估网格上给定状态配置的此映射的例程,非线性求解器会执行其他所有操作。(如果您最初的猜测很差,也许您需要多个起点。)

如果上述描述对您来说不够详细,维基百科http://en.wikipedia.org/wiki/Direct_multiple_shooting_method有一个有用的过程描述。那里引用的 Stoer/Bulirsch 的书提供了完整的细节。

我不知道用Python怎么做,但是你要在文献中寻找的关键字是“拍摄方法”。这是解决具有初始值和最终值约束的问题的方法的名称。

AUTO可以解决两点BVP,有python接口,安装比较容易。http://www.ma.hw.ac.uk/~gabriel/auto07/node6.html

如果你想先解决 P(t) 并将其作为输入提供给另一个 ODE,那么设置它的有效方法是使用 PyDSTool。PyDSTool 很容易在任何平台上安装,请参阅http://pydstool.sf.net默认情况下,它只会对您先前计算的解决方案使用线性插值(因此以精细的时间分辨率计算)。但是,即使使用自适应积分器,您也可以强制 PyDSTool 精确地步进到所需的时间点(尽管这可能效率低下并导致不准确)。但是,如果最大时间步长足够小,第二个系统的线性插值和快速积分器(内置 Dopri)意味着您可以适应这样的“常规”系统。