MPC模型预测控制算法(详细)

本文学习自华南理工大学龙胆也大佬,融入自己的思考和理解总结得到!

MPC三要素:

1、模型

2、预测

3、滚动优化

4、误差补偿

该模型与其它主流算法的对比:

总结:MPC适合大部分没有精确模型,或者阶次很高、非线性很强、约束很多的模型。

注意

MPC基于的模型不止一种。有传递函数,状态空间方程,也有数值模型,例如脉冲响应和阶跃响应。

本文主要讲阶跃响应序列。

正文

MPC里面滚动优化的核心是二次规划 

二次规划的目标函数为二次多项式:$J(x)=a x^{2}+b x+c$

二次多项式的画法要不就是开口向上或者开口向下。

拐弯点即极值点,就是二次规划目标函数的最优解。

为了找最优解,需要求导数为零的时候。

P是预测步长。假如K是当前时刻,可以往后面去预测 y(K+1) , y(K+2) ..... y(K+P),P可以从1开始到无穷大。

而M是控制步长,我们只能控制当前时刻的输入,因为现在永远早于预测,否则就不叫预测了。

即Δu(K),Δu(K + 1)....... Δu(K + M - 1

如何理解MPC模型?

P个时间周期的数据,直至PT时刻。

然后每个时刻都采集输出,y(a1),y(aP)。

根据线性系统的叠加原理:

ps:K代表某时刻。

$y(K)=a_{1} \cdot u(K-1)+a_{2} \cdot u(K-2)+\cdots+a_{M} \cdot u(K-M)$

我们把上面这个公式写成增量式:

$\Delta y(K)=a_{1} \cdot \Delta u(K-1)+a_{2} \cdot \Delta u(K-2)+\cdots+a_{M} \cdot \Delta u(K-M)$

可能会疑问,为什么最后是a_{M}因为我们能控制的只有当下,也就是M个步长可以控制,而不是P,因为P = M + 1

如何理解MPC的预测?

因为我们永远只能基于当下和之前来预测未来

预测第三个状态时,我们要基于第一次和第二次的经验。

直到...

最后我们用求和公式:

$\sum_{i=1}^{M} \cdot a_{i} \cdot \Delta u(K+P-i)$

总结一下:

新的预测输出 = Δ输出 + 原有预测输出

$\hat{Y}_{0}=A \cdot \Delta u+Y_{0}$

个人理解,主要是为了对比预测输出,一个是准确的预测输出,一个是根据以前的预测输出得到的预测输出。

写成

$\begin{array}{r}{\left[\begin{array}{c}\hat{Y}_{0}(k+1) \\ \hat{Y}_{0}(k+2) \\ \vdots \\ \hat{Y}_{0}(k+P)\end{array}\right]=\left[\begin{array}{cccc}a_{1} & 0 & \cdots & 0 \\ a_{2} & a_{1} & \cdots & 0 \\ \vdots & \vdots & & \vdots \\ a_{p} & a_{p-1} & \cdots & a_{p+M-1}\end{array}\right]\left[\begin{array}{c}\Delta u(K) \\ \Delta u(K+1) \\ \vdots \\ \Delta u(K+M)\end{array}\right]} \\ \\ +\left[\begin{array}{c}Y_{0}(K+1) \\ Y_{0}(K+2) \\ \vdots \\ Y_{0}(K+P)\end{array}\right]\end{array}$

如何理解MPC的滚动优化?

一、目标函数

$J(\Delta u)=a \cdot \Delta u^{2}+b \cdot \Delta u+c$

二、目标函数的求解

可以用matlab

也可以求导为0(基于这个二次多项式),得到最优解\Delta u

但是这个\Delta u是矩阵。我们选择矩阵中第一个数据为当前时刻的输入增量即可

滚动优化首先我们要知道它的期望轨迹。

可以用一阶滤波去模拟期望轨迹,即:

$\omega(k+i)=\alpha^{i} y(k)+\left(1-\alpha^{i}\right) y_{target}$

ps:y_{target}是目标值,y(k)是当前值

约束条件 0< \alpha <1

\alpha越小,则期望轨迹越陡;\alpha越大,则期望轨迹越缓慢

滚动优化第二步我们要如何设计目标函数J 

目标函数设计原则

1、目标一:离目标越近越好

$J_{1}=\sum_{i=1}^{p}[y(k+i)-w(k+i)]^{2}$

我们用一个求和函数,求P次,当前时刻的预测值当前时刻期望的预测值偏离多远,然后用平方是为了把正负给取消掉。

所以这个公式意味着我希望系统的预测与期望的轨迹接近。

2、目标二:能量越小越好

比如这个图,我肯定不希望系统绕个大弯去接近target。而是应该就近原则快速到达目标位置。

$J_{2}=\sum_{j=1}^{M}[\Delta u(K+j -1)]^{2}$

这里求和函数是M次,能量就是跟控制量\Delta u(K+i -1)有关,这里是能量的变化大小。那么平方就是不管是正负它也是在消耗能量。

最后,我们把完整的目标函数写出来。

根据你的需求,更看重目标一还是目标二,你可以自己去调整它们的相对大小

最好还是q + r = 1

比如我q为0.1,r为0.9。说明我希望能量小更重要。

如果q为0.9,r为0.1。说明我希望它靠近目标更快一点。

我们再把它写成矩阵的形式

$J=(Y-W)^{\top} \cdot Q \cdot(Y-W)+\Delta U^{\top} \cdot R \cdot \Delta U$

$\frac{\Delta J(\Delta u)}{\Delta(\Delta u)}=0$

得到这个公式,解得ΔU。(这个公式跟代码有很重要的关系,一定要搞懂!)

ΔU是一个Mx1的矩阵,我们控制增量取当前时刻的\Delta (K)加到系统的输入量里面就可以了

$\left[\begin{array}{c}\\\Delta (K) \\ \vdots \\ \Delta (K+M-1)\end{array}\right]$

MPC反馈矫正,补偿误差

K作为当前时刻,要预测P个,从下一时刻K+1开始:

$\hat{Y}_{0}(K+1) \cdots \hat{Y}_{0}(K+P)$

在K+1时刻,这个是实际值的输出

所以,误差 = 下一时刻实际值 - 当前时刻预测值

很容易理解,一个是从K时刻预测K+1的输出,一个是真真切切到达K+1时刻通过传感器等得到的输出。

e(K+1) = {y}(K+1) - \hat{Y}_{0}(K+1)

那么有误差我们肯定要做补偿。

补偿值 = 预测输出值 + 误差值

ps:h作为补偿系数设为0.5

为什么补偿{e}(K+1),就是因为现在是K时刻在做预测,我们要预测K+1,K+2 ... K+P,相当于一次性预测完。

然后K+1时刻时,我们预测K+2 ... K+P+1,那么到时补偿就变为{e}(K+2)

K时刻:

{y}_{correct}(K+1) = \hat{Y}_{0}(K+1) +{h}_{1}× {e}(K+1)

{y}_{correct}(K+2) = \hat{Y}_{0}(K+2) +{h}_{2}× {e}(K+1)

 {y}_{correct}(K+P) = \hat{Y}_{0}(K+P) +{h}_{P}× {e}(K+1)

把他写成矩阵的形式

那K+1时刻,预测值变为:

$\hat{Y}_{0}(K+2) \quad \hat{Y}_{0}(K+3) \quad\hat{Y}_{0}(K+4) \cdots\hat{Y}_{0}(K+P+1)$

\hat{Y}_{0}=S \cdot Y_{correct},S是移位矩阵

<think>好的,用户现在问的是关于MPC模型预测控制算法的代码介绍。首先,我需要回忆之前对话的内容,之前用户问过智能车竞赛中的抗饱和控制,其中提到了MPC是常用方法之一。现在用户可能想深入了解一下MPC的具体实现,尤其是在代码层面。 用户可能是在参加智能车竞赛或者类似的比赛,需要实际编写代码来实现控制算法。他们的需求不仅仅是理论,而是具体的代码结构和实现方法。因此,我需要提供一个清晰的代码框架,同时解释关键部分,比如模型建立、预测、优化等步骤。 接下来,我需要考虑用户可能的背景。他们可能是学生或者刚接触控制算法的开发者,对MPC有一定了解,但需要实际的代码示例来理解如何实现。因此,代码需要简洁易懂,同时配合必要的注释和解释,帮助他们理解每个部分的作用。 用户可能没有说出来的深层需求是希望了解如何将理论转化为代码,特别是如何处理优化问题,可能涉及到如何使用现有的库,比如Python中的cvxpy或者C++的ACADO。此外,他们可能关心实时性的问题,因为在实际的嵌入式系统中,计算资源有限,需要高效的算法。 我需要确保提供的代码示例既能展示MPC的核心思想,又不过于复杂。可能需要选择一个简单的系统,比如倒立摆或小车模型,这样用户容易理解。同时,要提到不同语言和工具的选择,比如Python适合仿真,而C++更适合嵌入式部署。 另外,用户可能对MPC中的各个步骤,如状态空间模型、目标函数、约束条件、优化求解器等部分感兴趣,需要详细解释这些部分在代码中的体现。还要指出实际应用中需要注意的问题,比如计算延迟、模型准确性等,以及如何调整参数来平衡性能和实时性。 最后,要总结关键点,帮助用户快速抓住重点,并提供进一步学习的资源,比如推荐书籍或开源项目,让他们可以继续深入学习和应用。</think>以下是关于**模型预测控制MPC算法**的代码实现逻辑和关键步骤的简介,结合一个简化示例(如小车位置控制)进行说明。实际应用中需根据具体模型调整参数和约束。 --- ### **1. MPC的核心思想** MPC通过**滚动优化**和**反馈校正**实现控制: 1. **预测模型**:基于系统动力学模型,预测未来一段时间内的状态变化。 2. 优化目标:最小化预测状态与期望状态的偏差,同时考虑控制输入的约束。 3. 实时调整:每次仅执行优化后的第一个控制量,并在下一周期重新优化。 --- ### **2. 代码框架(Python示例)** 以**小车位置控制**为例(假设状态量为位置和速度,控制量为力): #### **步骤1:定义系统模型** ```python import numpy as np from cvxpy import * # 离散化状态空间模型(A为状态矩阵,B为输入矩阵) dt = 0.1 # 时间步长 A = np.array([[1, dt], [0, 1]]) # 状态转移矩阵 B = np.array([[0.5*dt**2], [dt]]) # 输入矩阵 nx = A.shape[0] # 状态维度(位置、速度) nu = B.shape[1] # 输入维度(力) ``` #### **步骤2:设定MPC参数** ```python N = 10 # 预测步长(时间窗口) Q = np.diag([10, 1]) # 状态权重矩阵(重视位置误差) R = np.eye(nu) * 0.1 # 输入权重矩阵(限制控制量) x_target = np.array([5, 0]) # 目标状态(位置=5,速度=0) u_max = 2.0 # 控制输入的最大绝对值 ``` #### **步骤3:构建优化问题** ```python # 定义优化变量 x = cvxpy.Variable((nx, N+1)) # 状态序列(从k=0到k=N) u = cvxpy.Variable((nu, N)) # 控制输入序列(从k=0到k=N-1) # 初始状态约束 constraints = [x[:, 0] == x_current] # x_current为当前测量值 # 系统动力学约束 for k in range(N): constraints += [ x[:, k+1] == A @ x[:, k] + B @ u[:, k], # 状态更新 cvxpy.abs(u[:, k]) <= u_max # 控制量约束 ] # 目标函数(最小化状态偏差和控制量) cost = 0 for k in range(N): cost += cvxpy.quad_form(x[:, k] - x_target, Q) # 状态误差 cost += cvxpy.quad_form(u[:, k], R) # 控制量惩罚 # 设置优化问题 problem = cvxpy.Problem(cvxpy.Minimize(cost), constraints) ``` #### **步骤4:实时求解并应用控制量** ```python # 假设当前状态x_current已通过传感器获取 x_current = np.array([0, 0]) # 初始位置为0,速度为0 # 求解优化问题 problem.solve(solver=cvxpy.ECOS) # 使用高效凸优化求解器 # 提取第一个控制量并执行 u_opt = u[:, 0].value print("当前控制量:", u_opt) ``` --- ### **3. 关键代码解释** - **预测模型**:通过状态方程 `x_{k+1} = A x_k + B u_k` 描述系统动态。 - **约束条件**:包括控制量幅值限制、状态方程约束等。 - **目标函数**:通过权重矩阵 `Q` 和 `R` 平衡跟踪精度与控制能耗。 - **实时性优化**:使用高效的凸优化求解器(如ECOS、OSQP)加快计算速度。 --- ### **4. 实际应用注意事项** 1. **模型精度**:若实际系统非线性较强,需对模型进行线性化或使用非线性MPC(计算复杂度更高)。 2. **计算延迟**:嵌入式平台(如STM32)需简化模型或降低预测步长 `N`。 3. **状态估计**:若状态不可直接测量(如位置需通过积分速度获得),需结合卡尔曼滤波。 4. **参数调试**:调整 `Q`、`R` 和 `N` 以平衡响应速度和稳定性。 --- ### **5. 扩展工具和库** - **Python**:`cvxpy`、`do-mpc`、`CasADi`(适合快速仿真)。 - **C++**:`ACADO`、`HPIPM`(适合嵌入式部署)。 - **MATLAB**:MPC工具箱(Simulink集成)。 --- ### **6. 示例代码的局限性** - 简化了系统模型(实际系统可能有摩擦、非线性等)。 - 未处理状态约束(如位置范围限制)。 - 需要根据实际硬件调整求解器和计算频率。 如果需要更具体的代码(如倒立摆控制、车辆轨迹跟踪),可进一步说明场景和模型细节!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值