基于模型预测MPC实现的车速控制,控制目标为燃油汽车,采用上下层控制器控制,上层mpc产生期望的加速度,下层采用自抗扰ADRC控制产生期望的节气门开度和制动压力,同时该算法可直接用于代码生成(可做实车试验实验),后续可以用于车速需求的控制(如acc,轨迹跟踪等)。 有对应复现资料。
在自动驾驶领域,车速的精准控制一直是研究重点。今天咱们来聊聊基于模型预测MPC实现的燃油汽车车速控制,这可是个有趣又实用的技术。
上下层控制器架构
我们采用上下层控制器来实现车速控制。上层是MPC,也就是模型预测控制。它的主要任务是根据车辆当前状态和目标车速,产生期望的加速度。下层则是自抗扰ADRC控制,它依据上层MPC给出的期望加速度,进一步产生期望的节气门开度和制动压力,最终实现对车辆速度的精准调控。
上层MPC - 期望加速度的生成
MPC的核心思想是基于车辆模型,预测车辆在未来一段时间内的状态,然后通过优化算法找到最优的控制输入(这里就是期望加速度),使得车辆能够尽可能接近目标车速。
假设我们有一个简单的车辆动力学模型,比如线性时不变模型:
import numpy as np # 定义车辆模型参数 A = np.array([[1, 0.1], [0, 1]]) B = np.array([[0.05], [0.1]])这里A是状态转移矩阵,B是控制输入矩阵。0.1代表离散化时间间隔,在实际中,这个值要根据车辆的实际响应特性以及采样频率来合理选择。这两个矩阵反映了车辆状态(位置和速度)如何随时间和控制输入(加速度)变化。
基于模型预测MPC实现的车速控制,控制目标为燃油汽车,采用上下层控制器控制,上层mpc产生期望的加速度,下层采用自抗扰ADRC控制产生期望的节气门开度和制动压力,同时该算法可直接用于代码生成(可做实车试验实验),后续可以用于车速需求的控制(如acc,轨迹跟踪等)。 有对应复现资料。
然后,MPC的优化问题可以这样写(简化版):
# 定义预测时域和控制时域 Np = 10 Nu = 5 # 初始化权重矩阵 Q = np.diag([10, 1]) R = np.diag([1]) # 目标状态 x_ref = np.array([[100], [10]]) # 当前状态 x0 = np.array([[0], [0]]) def mpc(x0, x_ref): # 初始化状态和控制输入序列 X = np.zeros((2, Np + 1)) U = np.zeros((1, Nu)) X[:, 0] = x0.flatten() # 优化问题求解 for k in range(Nu): for j in range(Np - k): X[:, j + 1] = A.dot(X[:, j]) + B.dot(U[:, k]) cost = np.sum((X[:, 1:] - np.tile(x_ref, (1, Np))).T.dot(Q).dot(X[:, 1:] - np.tile(x_ref, (1, Np)))) + np.sum(U[:, k].T.dot(R).dot(U[:, k])) # 这里省略实际的优化求解步骤,实际可用如cvxpy库求解 # 简单示例:假设直接用梯度下降法找U使cost最小 dcost_du = 2 * B.T.dot(A.T.dot(X[:, 1:] - np.tile(x_ref, (1, Np))).dot(Q)) + 2 * R.dot(U[:, k]) U[:, k] = U[:, k] - 0.01 * dcost_du # 0.01为学习率,实际需调整 return U[0, 0]在这段代码里,Np是预测时域,也就是我们预测未来多少步车辆的状态,Nu是控制时域,即我们打算在接下来多少步内调整控制输入。Q和R是权重矩阵,用来平衡状态跟踪误差和控制输入的变化。x_ref是目标状态,x0是当前状态。mpc函数就是实现MPC的核心部分,它通过不断预测未来状态,计算代价函数,并尝试调整控制输入U来最小化代价函数,最终返回第一步的控制输入,也就是期望加速度。
下层ADRC - 节气门开度和制动压力控制
自抗扰控制ADRC能够有效应对系统的不确定性和外部干扰。它通过扩张状态观测器(ESO)实时估计系统的状态和干扰,然后利用非线性反馈控制律来产生控制量。
简单示意代码如下:
class ADRC: def __init__(self, b0, beta01, beta02, beta1, beta2, alpha1, alpha2, delta): self.b0 = b0 self.beta01 = beta01 self.beta02 = beta02 self.beta1 = beta1 self.beta2 = beta2 self.alpha1 = alpha1 self.alpha2 = alpha2 self.delta = delta self.x1 = 0 self.x2 = 0 self.x3 = 0 def fal(self, e, alpha, delta): if np.abs(e) <= delta: return np.sign(e) * np.power(np.abs(e), alpha) else: return e / np.power(np.abs(e), 1 - alpha) def update(self, v, a_des): e1 = v - self.x1 self.x1 = self.x1 + 0.01 * (self.x2 - self.x3) self.x2 = self.x2 + 0.01 * self.beta01 * self.fal(e1, self.alpha1, self.delta) self.x3 = self.x3 + 0.01 * self.beta02 * self.fal(e1, self.alpha2, self.delta) u0 = a_des - self.x2 u = self.b0 * u0 + self.x3 return u在这个ADRC类里,b0,beta01,beta02,beta1,beta2,alpha1,alpha2,delta这些参数都是需要根据车辆实际特性调整的。fal函数是非线性函数,用于构建非线性反馈控制律。update函数根据当前车速v和上层MPC给出的期望加速度a_des来更新ADRC的内部状态,并计算出最终的控制量u,这个u可以对应到节气门开度或者制动压力的控制信号。
实际应用拓展
这种基于MPC和ADRC的车速控制算法不仅能用于基本的车速维持,后续还可以拓展到自适应巡航(ACC),通过实时监测前车距离和速度,动态调整本车车速。在轨迹跟踪方面,结合车辆的位置信息和规划好的轨迹,MPC产生的期望加速度可以引导车辆精确沿着轨迹行驶。
而且,这个算法可直接用于代码生成,非常适合做实车试验。同时,还有对应复现资料,方便大家深入研究和实践。无论是自动驾驶爱好者还是相关领域的研究人员,都可以基于这些知识和资料,进一步探索车辆速度控制的奥秘,为自动驾驶技术的发展添砖加瓦。