算法详解+代码(无人驾驶车辆模型预测控制第四章)

这篇具有很好参考价值的文章主要介绍了算法详解+代码(无人驾驶车辆模型预测控制第四章)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.MPC模型预测控制理论推导

首先对汽车运动学模型进行建模:

imp_speed,算法

设后轴速度为,前轴行速度为考虑后轴轴心的速度约束,得到和后轴速度的关系如下:

                                           imp_speed,算法

考虑到前后轴速度约束的运动学方程为:

     imp_speed,算法

设后轴行驶中心为,前轴行驶中心为,根据前后轴之间的几何约束关系可得到:

                                             imp_speed,算法

将上述三个公式联立可得到横摆角速度的表达式为:

                                                 

由横摆角速度和车速可得到车辆的转向半径和车轮偏角:

                                              

即可得到矩阵形式的汽车运动学的表达方程:

                                                

由此方程可知,这个动力学系统可以看成是由两个输入,三个输出构成的控制系统,抽象成函数为:

                                                

设我们期望的参考轨迹点为,在参考点附近对该抽象映射函数进行泰勒展开以线性化,并且忽略高阶项:

                                 imp_speed,算法              

考虑到最终我们控制的是误差的增量,设为误差:

                                        ​​​​​​​       

整理计算后得到:

                                                imp_speed,算法  

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​       

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​       

MPC的基本原理,就是在每个计算时域内,求解一个二次规划问题,并且以求解得到的二次规划问题的最优解作为下一个步长的输入,从而对未来多个时间步长内的状态量进行预测控制。在无人驾驶汽车中,目标函数要保证能够快速且平稳的跟踪期望轨迹,就要求我们对系统状态量做出优化。此处我们对状态量进行优化控制,以便快速平稳的跟踪轨迹。

代价函数(或优化函数)如下:

        ​​​​​​​        ​​​​​​​        imp_speed,算法

其中,Q,R为权重矩阵,反应了我们对状态量的侧重程度,等号左边的第一项是我们要控制的轨迹跟踪效果,反映了无人车对轨迹的跟随能力,第二项为对输出变化的约束。输出的u为前轮转角和速度。

由于我们最终控制的是误差的增量,对上述方程进行变形得到:

        ​​​​​​​        ​​​​​​​        imp_speed,算法

其中为松弛因子,为松弛因子系数

MPC具体迭代过程如下:

imp_speed,算法

为方便后续的理论分析和计算,将状态变量和输出的增量矩阵写成一个矩阵:

                                               

由前面状态量的迭代关系可得到:

        ​​​​​​​        ​​​​​​​        ​​​​  imp_speed,算法

化简得到新的状态空间表达式:

                                  imp_speed,算法

                                  

其中为的单位阵,为单位阵,A为imp_speed,算法的矩阵,B为imp_speed,算法的矩阵,为状态向量矩阵的维数,为输出向量的维数。

  MPC滚动预测计算结果和流程如下,其中预测时域,为控制时域,在我们的计算过程中取60,取30,状态量计算过程:

imp_speed,算法

输出的计算过程:

imp_speed,算法

由上述方程可得到:

                                imp_speed,算法

                                imp_speed,算法

因为目标函数为  imp_speed,算法

其中imp_speed,算法这一项是输出的增量,也就是,令为矩阵,得到:

        ​​​​​​​        imp_speed,算法

忽略不影响最优结果的常数项imp_speed,算法,化简得到:

                imp_speed,算法

将优化函数配凑成标准二次规划函数得到:

                imp_speed,算法

将代价函数表示成标准的二次规划函数,在优化求解时的代价函数为:

                imp_speed,算法

                

                

在有了代价函数之后,我们还要知道约束条件,MPC的约束条件有两个,分别为上下限约束和增量约束,上下限约束如下:

                imp_speed,算法

逐项计算他们的增量关系得到:

                imp_speed,算法

令:

                imp_speed,算法

                          imp_speed,算法

              

则最终得到的约束条件为:

                                       imp_speed,算法

增量约束的思想为,我们取每一次的增量都要小于我们人为设定的值:

              imp_speed,算法

即:

                                      

二.MPC代码实战(carsim+simulink)

第一步,选择车型,这一步无所谓,喜欢什么车选什么车,但是要注意轴距要和写的s-function一一对应:

imp_speed,算法

车辆基础参数如下,除了轴距之外,也没什么要注意的:

imp_speed,算法

下面是导入到simulink的接口配置:

输入的接口配置如下:

①IMP_SPEED:车辆行驶速度

②IMP_STEER_L1:左前轮转角

③IMP_STEER_R1:右前轮转角

④IMP_STEER_L2:左后轮转角,我们用不到,simulink中置0

⑤IMP_STEER_R2:右后轮转角,用不到,simulink模型中取0

imp_speed,算法

输出的接口配置如下:

①X0:carsim输出的X轴坐标

②Y0:carsim输出的Y轴坐标

③Yaw:carsim输出的航偏角

④Vx:carsim输出的速度

⑤Steer_SW:carsim输出的车辆前轮轮转角

imp_speed,算法

 仿真频率的设置如下:

imp_speed,算法

配置好工程之后,点击send to simulink将其发送到simulink,搭建具体的模型如下,xy graph为simulink的画图模块,我们为了方便对比,将车辆的实际行驶轨迹x0,y0和我们预设的理想轨迹x,y用to workspace模块导入到matlab的工作区间中然后画图:

imp_speed,算法

在导入到simulink之后,我们可以看到to workspace前面有out.的前缀,看着让人十分的不爽,下面是清除方法:

imp_speed,算法

点击设置打开:

imp_speed,算法

按步骤操作,将此处的对勾去掉即可。

单位换算模块:

imp_speed,算法

这两个地方为:

imp_speed,算法

下面是完整的MPC控制器脚本代码,可以自行复制,也可以对着教材一行行敲:

%主函数部分
function[sys,x0,str,ts]=MpcControll(t,x,u,flag)
switch flag
    case 0
    [sys,x0,str,ts]=mdlInitializeSizes;
    %初始化函数,对被控方程S-Function进行参数设置,类比构造类。
    case 2
    %更新离散状态量
    sys=mdlUpdates(t,x,u);
    %仅在离散系统中被调用,产生下一个状态
    case 3
    sys = mdlOutputs(t,x,u); 
    %计算输出量
    case {1,4,9}
    %无关的标志位
    sys = [];
 otherwise
  error(['unhandled flag = ',num2str(flag)]); % Error handling
end
%初始化主函数
    function [sys,x0,str,ts] = mdlInitializeSizes
    sizes = simsizes;
    sizes.NumContStates  = 0;
    sizes.NumDiscStates  = 6;%离散状态变量的个数
    sizes.NumOutputs     = 5;%输出量的个数[速度(km/h),前轮转角(deg)]
    sizes.NumInputs      = 3;%输入量的个数[X0,Y0,Yaw]
    sizes.DirFeedthrough = 1;
    sizes.NumSampleTimes = 1;
    sys = simsizes(sizes); 
    x0 =[0;0;0;0;0;0];             %状态变量初始化   
    global U;
    U=[0;0];
    %初始化时间
    str = [];             % 置空即可
    ts  = [0.05 0];       % 仿真时间格式:[period, offset]
 %更新离散状态函数
    function sys = mdlUpdates(t,x,u)%算完了X(k)然后算X(k+1)
    sys = x;
 %计算输出子函数
    function sys = mdlOutputs(t,x,u)
    global a b u_piao;
    global U; %store chi_tilde=[vel-vel_ref; delta - delta_ref]
    global kesi;
    tic
    Nx=3;%状态量的个数
    Nu =2;%控制量的个数
    Np =60;%预测步长
    Nc=30;%控制步长
    Row=10;%松弛因子
    fprintf('Update start, t=%6.3f\n',t)
    yaw_angle =u(3)*3.1415926/180;%CarSim输出的Yaw angle为角度,角度转换为弧度
%    %直线路径
%    r(1)=5*t; %ref_x-axis
%    r(2)=5;%ref_y-axis
%    r(3)=0;%ref_heading_angle
%    vd1=5;% ref_velocity
%    vd2=0;% ref_steering
%    %半径为25m的圆形轨迹, 圆心为(0, 35), 速度为5m/s
    X_ba=25*sin(0.2*t);     %X坐标
    Y_ba=35-25*cos(0.2*t);  %Y坐标
    fai_ba=0.2*t;           %航向角
    vd1=5;                  %速度
    vd2=0.104;              %转角
%     %半径为35m的圆形轨迹, 圆心为(0, 35), 速度为3m/s
%     r(1)=25*sin(0.12*t);
%     r(2)=25+10-25*cos(0.12*t);
%     r(3)=0.12*t;
%     vd1=3;
%     vd2=0.104;
	%半径为25m的圆形轨迹, 圆心为(0, 35), 速度为10m/s
%      r(1)=25*sin(0.4*t);
%      r(2)=25+10-25*cos(0.4*t);
%      r(3)=0.4*t;
%      vd1=10;
%      vd2=0.104;
%     %半径为25m的圆形轨迹, 圆心为(0, 35), 速度为4m/s
%      r(1)=25*sin(0.16*t);
%      r(2)=25+10-25*cos(0.16*t);
%      r(3)=0.16*t;
%      vd1=4;
%      vd2=0.104;
%参数矩阵
    kesi=zeros(Nx+Nu,1);%构造一个新矩阵
    kesi(1)=u(1)-X_ba;
    kesi(2)=u(2)-Y_ba;
    kesi(3)=yaw_angle-fai_ba;
    kesi(4)=U(1);
    kesi(5)=U(2);
    T=0.1;%采样时间为0.1s
    T_all=40;%总的仿真时间。设置总的仿真时间防止仿真溢出。
    L = 2.6; %轴距为2.6m
    t_d1=fai_ba;
%对矩阵参数进行初始化
    u_piao=zeros(Nu,1);%用来存放二次优化函数解出来的最优输出增量
    Q=100 * eye(Nx*Np,Nx*Np);%状态变量权重矩阵,行列都为状态变量维数*预测步长=3*60=180
    R=5*eye(Nu*Nc);%输出增量权重矩阵R,控制量最优权重矩阵
    
    a=[1    0   -vd1*sin(t_d1)*T;
       0    1   vd1*cos(t_d1)*T;
       0    0   1;]; %a为我们线性离散化后的第一个系数矩阵
    b=[cos(t_d1)*T        0;
       sin(t_d1)*T        0;
       tan(vd2)*T/L      vd1*T/(cos(vd2)^2);];%b为我们线性离散化后的第二个系数矩阵
%初始化状态矩阵X(k|t)
    A_cell=cell(2,2);
    B_cell=cell(2,1);
    A_cell{1,1}=a; %将a矩阵放到A_cell的第一行第一个位置
    A_cell{1,2}=b; %将b矩阵放到A_cell的第一行第二个位置
    A_cell{2,1}=zeros(Nu,Nx); %将2*3的零矩阵放到A_cell第二行的第一个位置
    A_cell{2,2}=eye(Nu); %将2*2的单位阵放到A_cell第二行的第二个位置
    B_cell{1,1}=b; %将b矩阵放到B_cell的第一行
    B_cell{2,1}=eye(Nu); %将2*2的单位阵放到B_cell第二行
    A=cell2mat(A_cell); %这里的A就是我们在推导下一时刻的状态空间时候的A
    B=cell2mat(B_cell); %这里的B就是我们在推导下一时刻的状态空间时候的B
    C=[ 1 0 0 0 0;
        0 1 0 0 0;
        0 0 1 0 0];%C矩阵是我们输出方程的系数矩阵
    PHI_cell=cell(Np,1);%这个PHI是我们通过总结规律得到的等式右边的第一个系数矩阵,60*1维度
    THETA_cell=cell(Np,Nc);%这里的THETA为我们通过总结规律的到的等式右边的第二个系数矩阵,60*30维度
    for j=1:1:Np
        PHI_cell{j,1}=C*A^j;
        for k=1:1:Nc
            if k<=j
            THETA_cell{j,k}=C*A^(j-k)*B;
            else 
            THETA_cell{j,k}=zeros(Nx,Nu);
            end
        end
    end
    PHI=cell2mat(PHI_cell);%将元胞数组转换成矩阵
    THETA=cell2mat(THETA_cell);  
%下面的函数参考教材即可
    H_cell=cell(2,2); %这里的H为我们二次规划中的H矩阵,以下来构造二次规划中的H矩阵
    H_cell{1,1}=THETA'*Q*THETA+R;
    H_cell{1,2}=zeros(Nu*Nc,1);
    H_cell{2,1}=zeros(1,Nu*Nc);
    H_cell{2,2}=Row; %松弛因子
    H=cell2mat(H_cell);
    error=PHI*kesi; 
    f_cell=cell(1,2);%f为二次规划的第二个向量
    f_cell{1,1} = 2*(error'*Q*THETA);
    f_cell{1,2} = 0;
    f=cell2mat(f_cell);%将元胞数组转化为矩阵
%约束条件
    A_t=zeros(Nc,Nc);%构造At矩阵,见教材第四章
    for p=1:1:Nc
        for q=1:1:Nc
            if q<=p 
                A_t(p,q)=1;
            else 
                A_t(p,q)=0;
            end
        end 
    end 
    A_I=kron(A_t,eye(Nu));%求直积
    Ut=kron(ones(Nc,1), U);%此处的U表示上一时刻的输出矩阵。
    umin=[-0.2;  -0.332];%见教材第四章的约束
    umax=[0.2;   0.332];
    delta_umin = [-0.05;  -0.0082];%最小值约束合集
    delta_umax = [0.05;  0.0082];%最大值约束合集
    Umin=kron(ones(Nc,1),umin);
    Umax=kron(ones(Nc,1),umax);
    %二次规划不等式约束 Ax <= b
    A_cons_cell={A_I zeros(Nu*Nc, 1); -A_I zeros(Nu*Nc, 1)};
    b_cons_cell={Umax-Ut;-Umin+Ut};
    A_cons=cell2mat(A_cons_cell);%(求解方程)状态量不等式约束增益矩阵,转换为绝对值的取值范围
    b_cons=cell2mat(b_cons_cell);%(求解方程)状态量不等式约束的取值
    %状态量约束
    M = 10;%松弛因子
    delta_Umin = kron(ones(Nc,1),delta_umin);
    delta_Umax = kron(ones(Nc,1),delta_umax);
    lb = [delta_Umin; 0];%求解二次规划时变量取值的上限
    ub = [delta_Umax; M];%求解二次规划时变量取值的下限
    %% 开始求解过程
    options = optimset('Algorithm','interior-point-convex');    
    [X, fval,exitflag]=quadprog(H, f, A_cons, b_cons,[], [],lb,ub,[],options);
    fprintf('quadprog EXITFLAG = %d\n',exitflag);
    %% 计算输出   
    u_piao(1)=X(1);%X1为二次规划控制时域内最优的速度控制增量
    u_piao(2)=X(2);%X2为二次规划最优前轮转角控制增量
    U(1)=kesi(4)+u_piao(1);%速度误差+速度误差增量
    U(2)=kesi(5)+u_piao(2);%转角误差+转角误差增量
    u_real(1) = U(1) + vd1;%再与下面的参考速度相加才是真正的速度
    u_real(2) = U(2) + vd2;%道理同上
    sys(1)=u_real(1); 
    sys(2)=u_real(2);
    sys(3)=X_ba;
    sys(4)=Y_ba;
    sys(5)=fai_ba;
    toc
























这里使用to worspace模块把理想轨迹数据和预测轨迹数据都发到工作区然后用plot函数画图:

plot(X,Y,'y'); % 使用plot函数将X和Y数据可视化成线图
hold on;
plot(X0,Y0,'r');
hold off;

运行结果如下:

imp_speed,算法

参考:

无人驾驶车辆模型预测控制第四章_falcone论文_瑞瑞瑞12123的博客-CSDN博客

《无人驾驶车辆模型预测控制》(第二版)第四章详细学习——算法部分_无人驾驶车辆模型预测控制 pdf_总系学不废的博客-CSDN博客

《无人驾驶车辆模型预测控制》(第二版)文章来源地址https://www.toymoban.com/news/detail-780460.html

到了这里,关于算法详解+代码(无人驾驶车辆模型预测控制第四章)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包