MPC轨迹跟踪|python

MPC轨迹跟踪 | python实现

基本概念

MPC问题推导及转换为QP问题的过程可以看这篇博客,这里直接给出结果。
J = 1 2 U ( t ) T P U ( t ) + q T U ( t ) s . t . G U ( t ) ≤ h U ( t ) = [ u 0 T , u 1 T , . . . , u N − 1 T ] ( N × n u , 1 ) T P = 2 C T Q ˉ C + R ˉ q = 2 C T Q ˉ T M x 0 \begin{aligned} &J = \frac{1}{2}U(t)^T P U(t) + q^T U(t)\\ &\begin{aligned} s.t. \quad G U(t) \leq h \end{aligned}\\ &U(t) = [u_0^T, u_1^T, ..., u_{N-1}^T]^T_{(N \times n_u, 1)}\\ &P = 2C^T\bar{Q}C + \bar{R}\\ &q = 2C^T\bar{Q}^TMx_0 \end{aligned} J=21U(t)TPU(t)+qTU(t)s.t.GU(t)hU(t)=[u0T,u1T,...,uN1T](N×nu,1)TP=2CTQˉC+Rˉq=2CTQˉTMx0

M = [ I A A 2 ⋮ A N ] ( N × n x , n x ) , C = [ 0 0 0 ⋯ 0 B 0 0 ⋯ 0 A B B Q ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ A N − 1 B A N − 2 B A N − 3 ⋯ B ] ( ( N + 1 × n x ) , ( N × n u ) ) M = \begin{bmatrix} I\\ A\\ A^2\\ \vdots\\ A^N \end{bmatrix}_{(N \times n_x, nx)}, C = \begin{bmatrix} 0 & 0 & 0 & \cdots & 0 \\ B & 0 & 0 & \cdots & 0 \\ AB & B & Q & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ A^{N-1}B & A^{N-2}B & A^{N-3} & \cdots & B \\ \end{bmatrix}_{((N+1 \times n_x), (N \times n_u))} M= IAA2AN (N×nx,nx),C= 0BABAN1B00BAN2B00QAN3000B ((N+1×nx),(N×nu))

Q ˉ = [ Q 0 0 ⋯ 0 0 Q 0 ⋯ 0 0 0 Q ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ Q f ] ( ( N + 1 ) × n x , ( N + 1 ) × n x ) , R ˉ = [ R 0 0 ⋯ 0 0 R 0 ⋯ 0 0 0 R ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ R ] ( N × n u , N × n u ) \bar{Q} = \begin{bmatrix} Q & 0 & 0 & \cdots & 0 \\ 0 & Q & 0 & \cdots & 0 \\ 0 & 0 & Q & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & Q_f \\ \end{bmatrix}_{((N+1) \times n_x, (N+1) \times n_x)}, \bar{R} = \begin{bmatrix} R & 0 & 0 & \cdots & 0 \\ 0 & R & 0 & \cdots & 0 \\ 0 & 0 & R & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & R \\ \end{bmatrix}_{(N \times n_u, N \times n_u)} Qˉ= Q0000Q0000Q0000Qf ((N+1)×nx,(N+1)×nx),Rˉ= R0000R0000R0000R (N×nu,N×nu)
式中, A , B A, B A,B表示系统矩阵; Q , R , Q f Q, R, Q_f Q,R,Qf分别表示系统状态、系统输入和终端状态的代价矩阵,自行设置; n x , n u n_x, n_u nx,nu分别表示系统状态和控制输入的维度。

MPC问题的输入为当前系统状态 x 0 x_0 x0,输出为最优的控制序列 U ( t ) U(t) U(t),执行时仅适用输出序列 U ( t ) U(t) U(t)中的第一个控制输出 u 0 u_0 u0

求解步骤

  1. 建立MPC问题,包括目标函数和约束
  2. 将MPC问题转换为QP问题
  3. 调用QP求解器进行优化求解得到控制序列
  4. 取控制序列中的第一个控制输入执行

python实现轨迹跟踪

实现效果


图1 MPC轨迹跟踪效果示意

这里用MPC控制以后轴中心为车辆原点的模型进行轨迹跟踪,用这个模型是因为方便线性化进行控制,该模型的线性化推导过程可以参考这篇博客

MPC求解

MPC轨迹跟踪演示的完整代码在github仓库,这里仅给出MPC求解部分,代码里用了qpsolvers进行求解,后台调用的是osqp。

import math
import osqp
import numpy as np
from scipy import sparse
from qpsolvers import solve_qp

class MPC:
    def __init__(self, Ad, Bd, Q, R, Qf, N = 10):
        self.Ad = Ad
        self.Bd = Bd
        self.Q = Q
        self.R = R
        self.Qf = Qf
        self.N = N    # 预测步数
        self.nx = Bd.shape[0]
        self.nu = Bd.shape[1]

    def solve(self, x0, Ad, Bd, Q, R, Qf, N = 10):
        self.Ad = Ad
        self.Bd = Bd
        self.Q = Q
        self.R = R
        self.Qf = Qf
        self.N = N    # 预测步数
        self.nx = Bd.shape[0]
        self.nu = Bd.shape[1]

        A_powers = []
        for i in range(self.N + 1):
            A_powers.append(np.linalg.matrix_power(Ad, i))

        C = np.zeros(((self.N + 1) * self.nx, self.N * self.nu))
        M = np.zeros(((self.N + 1) * self.nx, self.nx))
        for i in range(self.N + 1):
            for j in range(self.N):
                if i - j - 1 >= 0:
                    C_ij = A_powers[i - j - 1] * self.Bd
                    C[i * self.nx : (i + 1) * self.nx, j * self.nu : (j + 1) * self.nu] = C_ij
                else:
                    C_ij = np.zeros((self.nx, self.nu))
                    C[i * self.nx : (i + 1) * self.nx, j * self.nu : (j + 1) * self.nu] = C_ij
            M[i * self.nx : (i + 1) * self.nx, :] = A_powers[i]

        Q_bar = np.kron(np.eye(self.N + 1), Q)
        Q_bar[self.N * self.nx : (1 + self.N) * self.nx, self.N * self.nx : (1 + self.N) * self.nx:] = Qf
        R_bar = np.kron(np.eye(self.N), R)
        E = M.T * Q_bar * C

        P = 2 * C.T * Q_bar * C + R_bar
        q = 2 * E.T * x0

        # Gx <= h
        G_ = np.eye(self.N * self.nu)
        G = np.block([                   # 不等式约束矩阵
            [G_, np.zeros_like(G_)],
            [np.zeros_like(G_), -G_]
        ])
        h = np.vstack(np.ones((2 * self.N * self.nu, 1)) * 999) # 不等式约束向量

        # Ax = b
        A = None # 等式约束矩阵
        b = None # 等式约束向量

        # 转换为稀疏矩阵的形式能加速计算
        P = sparse.csc_matrix(P)
        q = np.asarray(q)
        if G is None:
            pass
        else:
            G = sparse.csc_matrix(G)
        if A is None:
            pass
        else:
            A = sparse.csc_matrix(A)

        res = solve_qp(P, q, G, h, A, b, solver="osqp")

        return res
  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MPC(Model Predictive Control)是一种先进的控制方法,用于实现轨迹跟踪。下面是一个使用Python实现MPC轨迹跟踪的示例代码: ```python import numpy as np from scipy.optimize import minimize # 定义MPC控制器类 class MPCController: def __init__(self, dt, N, Q, R): self.dt = dt # 时间步长 self.N = N # 预测步数 self.Q = Q # 状态权重矩阵 self.R = R # 控制权重矩阵 def cost_function(self, u, x_ref, x0): cost = 0 x = x0.copy() for i in range(self.N): x = self.update_state(x, u[i]) cost += np.dot((x - x_ref[i]).T, np.dot(self.Q, (x - x_ref[i]))) + np.dot(u[i].T, np.dot(self.R, u[i])) return cost def update_state(self, x, u): # 更新状态方程 # TODO: 根据具体的系统动力学方程进行实现 pass def optimize(self, x_ref, x0, u0): bounds = [(0, 1)] * self.N # 控制输入的边界 res = minimize(self.cost_function, u0, args=(x_ref, x0), bounds=bounds) return res.x # 定义轨迹跟踪控制器参数 dt = 0.1 # 时间步长 N = 10 # 预测步数 Q = np.diag([1, 1, 1, 1]) # 状态权重矩阵 R = np.diag([0.1, 0.1]) # 控制权重矩阵 # 创建MPC控制器对象 mpc_controller = MPCController(dt, N, Q, R) # 定义参考轨迹和初始状态 x_ref = np.array([[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]) # 参考轨迹 x0 = np.array([0, 0, 0, 0]) # 初始状态 u0 = np.zeros((N, 2)) # 初始控制输入 # 优化控制输入 u_opt = mpc_controller.optimize(x_ref, x0, u0) # 输出优化后的控制输入 print(u_opt) ``` 这是一个简化的示例,你需要根据具体的系统动力学方程来实现`update_state`函数。在示例中,我们使用`scipy.optimize.minimize`函数来优化控制输入,通过最小化代价函数来实现轨迹跟踪
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值