無人車両の転がり機構と転がり安定性基準

安定性解析:ヨー安定性、ロール安定性
動的モデル - 合理的な制御境界を見つけ、効果的な操縦安定性基準を策定 - オンライン評価;
安定性基準は性能評価関数に反映 - 評価関数 最適化 - 非線形下での無人運転の動作安定性を正確に反映ヨーや横滑りなどの動的制約。
モデル予測—追従制御—高速安定性、直面する課題—モデルの複雑さとリアルタイム計算
高精度モデル—有効性、予測時間領域
の延長 動的モデルの離散化手法
ゼロ次ホールドと一次次数維持
ヨーレート、横方向速度、タイヤの最大コーナリングフォース、包絡線に基づくヨー安定性基準の導出
タイヤ横滑り角の値の範囲
道路環境の制約、アクチュエータの飽和制約

パラメータ 価値
予測時間領域長 Np 20
Ns 10
短いステップ サイズの離散化ステップ サイズ 0.05
長いステップ サイズの離散化ステップ サイズ 0.2
タイヤスリップ角制限 0.1
車両スリップ角 0.4
車両横滑り角変化率 0.08
パラメータ 価値
コース偏差の極値 0.15
極端な横方向の偏り 2
針路変化率の極値 1
側面重量 500
見出し重量 500
スラックファクターの重み 50
体重が増える 5

車両ロールのメカニズム解析
車両ロール: トリップロール、曲線運動による
ロール ロール安定性基準
難易度: ロールがいつ始まるかを予測するのは困難; 時間
変化する道路曲率と側勾配角度 車両のロール傾向の予測。
ロール機構 - ゼロモーメントポイント (ZMP) でのロール安定性基準
トラッキング期待値: 横方向の偏差、機首方位の偏差

function [sys,x0,str,ts] =chapter8_3_3(t,x,u,flag)
%***************************************************************%
% This is a Simulink/Carsim joint simulation solution for safe driving
% envelope control of high speed autonomous vehicle
% Linearized spatial bicycle vehicle dynamic model is applied.
% No successive linearizarion. No two time scale of prediction horizon
% Constant high speed, curve path tracking 
% state vector =[beta,yawrate,e_phi,s,e_y]
% control input = [steer_SW]
% many other parameters are also outputed for comparision.

% Input:
% t是采样时间, x是状态变量, u是输入(是做成simulink模块的输入,即CarSim的输出),
% flag是仿真过程中的状态标志(以它来判断当前是初始化还是运行等)

% Output:
% sys输出根据flag的不同而不同(下面将结合flag来讲sys的含义), 
% x0是状态变量的初始值, 
% str是保留参数,设置为空
% ts是一个1×2的向量, ts(1)是采样周期, ts(2)是偏移量
%---------------------------------------------------------------%
% Published by: Kai Liu
% Email:[email protected]
% My homepage: https://sites.google.com/site/kailiumiracle/  
%***************************************************************% 
    switch flag,
        case 0 % Initialization %
            [sys,x0,str,ts] = mdlInitializeSizes; % Initialization
        case 2 % Update %
            sys = mdlUpdates(t,x,u); % Update discrete states
        case 3 % Outputs %
            sys = mdlOutputs(t,x,u); % Calculate outputs
        case {1,4,9} % Unused flags
            sys = [];            
        otherwise % Unexpected flags %
            error(['unhandled flag = ',num2str(flag)]); % Error handling
    end %  end of switch    
%  End sfuntmpl

function [sys,x0,str,ts] = mdlInitializeSizes
%==============================================================
% Initialization, flag = 0,mdlInitializeSizes
% Return the sizes, initial conditions, and sample times for the S-function.
%==============================================================
sizes = simsizes;%用于设置模块参数的结构体用simsizes来生成
sizes.NumContStates  = 0;  %模块连续状态变量的个数
sizes.NumDiscStates  = 6;  %模块离散状态变量的个数,实际上没有用到这个数值,只是用这个来表示离散模块
sizes.NumOutputs     = 15;  %S函数的输出,包括控制量和其它监测量
sizes.NumInputs      = 38; %S函数模块输入变量的个数,即CarSim的输出量
sizes.DirFeedthrough = 1;  %模块是否存在直接贯通(direct feedthrough). 1 means there is direct feedthrough.
% 直接馈通表示系统的输出或可变采样时间是否受到输入的控制。
% a.  输出函数(mdlOutputs或flag==3)是输入u的函数。即,如果输入u在mdlOutputs中被访问,则存在直接馈通。
% b.  对于一个变步长S-Function的“下一个采样时间”函数(mdlGetTimeOfNextVarHit或flag==4)中可以访问输入u。
% 正确设置直接馈通标志是十分重要的,因为它影响模型中块的执行顺序,并可用检测代数环。
sizes.NumSampleTimes = 1;  %模块的采样次数,>=1

sys = simsizes(sizes);    %设置完后赋给sys输出

x0 = zeros(sizes.NumDiscStates,1);%initial the  state vector, of no use

str = [];             % 保留参数,Set str to an empty matrix.

ts  = [0.05 0];       % ts=[period, offset].采样周期sample time=0.05,50ms 

%--Global parameters and initialization
[y, e] = func_RLSFilter_Calpha_f('initial', 0.95, 10, 10);
[y, e] = func_RLSFilter_Calpha_r('initial', 0.95, 10, 10);

    global InitialGapflag; 
    InitialGapflag = 0; % the first few inputs don't count. Gap it.
    
    global VehiclePara; % for SUV
    VehiclePara.m   = 1600;   %m为车辆质量,Kg; Sprung mass = 1370
    VehiclePara.g   = 9.81;
    VehiclePara.hCG = 0.65;%m
    VehiclePara.Lf  = 1.12;  % 1.05
    VehiclePara.Lr  = 1.48;  % 1.55
    VehiclePara.L   = 2.6;  %VehiclePara.Lf + VehiclePara.Lr;
    VehiclePara.Tr  = 1.565;  %c,or 1.57. 注意半轴长度lc还未确定
    VehiclePara.mu  = 0.85; % 0.55; %地面摩擦因数
    VehiclePara.Iz  = 2059.2;   %I为车辆绕Z轴的转动惯量,车辆固有参数  
    VehiclePara.Ix  = 700.7;   %I为车辆绕Z轴的转动惯量,车辆固有参数  
    VehiclePara.Radius = 0.387;  % 轮胎滚动半径   
    
    global MPCParameters; 
    MPCParameters.Np  = 20;% predictive horizon Assume Np=Nc
    MPCParameters.Ns  = 10; %  Tsplit
    MPCParameters.Ts  = 0.05; % the sample time of near term
    MPCParameters.Tsl = 0.2; % the sample time of long term       
    MPCParameters.Nx  = 6; %the number of state variables
    MPCParameters.Ny  = 2; %the number of output variables      
    MPCParameters.Nu  = 1; %the number of control inputs
    
    global CostWeights; 
    CostWeights.Wephi   = 100; %state vector =[beta,yawrate,e_phi,s,e_y]
    CostWeights.Wey     = 10;
    CostWeights.Ddeltaf = 10;
    CostWeights.deltaf  = 1; % 可能用不到
    CostWeights.Wshar   = 500;
    CostWeights.Wshr    = 500;

    
    global Constraints;  
    Constraints.dumax   = 0.1/MPCParameters.Ts;     % Units: rad,0.08rad/s--4.6deg/s  
    Constraints.umax    = 0.4;      % Units: rad appro.23deg
    
    Constraints.arlim   = 6*pi/180; % alpha_lim=6deg~ 0.1047rad
    Constraints.rmax    = 1.0; % rr_max = 1rad/s    
    
    ar_slackMax         = 6*pi/180; % rad
    rmax_slackMax       = 1.0;
    Constraints.Sshmax  = [ar_slackMax; rmax_slackMax];
    
    Constraints.DPhimax = 60*pi/180;  %  最大航向角偏差60deg
    Constraints.Dymax   = 1.7; % 3.0;    cross-track-error max 3m

    global WayPoints_IndexPre;
    WayPoints_IndexPre = 1;
    
    global Reftraj;
%     Reftraj = load('WayPoints_Alt3fromFHWA_Overall_Station_Bank.mat');
    Reftraj = load('WayPoints_Alt3fromFHWA_Samples.mat');    
    
    global FeedbackCorrects;
    FeedbackCorrects.StatePred = zeros(6,1);
    FeedbackCorrects.Ctrlopt   = 0;
     
%  End of mdlInitializeSizes

function sys = mdlUpdates(t,x,u)
%==============================================================
% Update the discrete states, flag = 2, mdlUpdate
% Handle discrete state updates, sample time hits, and major time step
% requirements.
%==============================================================
%  基本没有用到这个过程;在后期的程序模块化时可以继续开发这个功能。
    sys = x;    
% End of mdlUpdate.

function sys = mdlOutputs(t,x,u)
%==============================================================
% Calculate outputs, flag = 3, mdlOutputs
% Return the block outputs. 
%==============================================================

%***********Step (1). Parameters Initialization ***************************************%

global InitialGapflag;
global VehiclePara;
global MPCParameters; 
global CostWeights;     
global Constraints;
global WayPoints_IndexPre;
global Reftraj;
global FeedbackCorrects;


Ctrl_SteerSW    = 0;
t_Elapsed       = 0;
PosX            = 0;
PosY            = 0;
PosPsi          = 0;
Vel             = 0;
e_psi           = 0;
e_y             = 0;
fwa_opt         = 0;
Shenvelop_hat   = [0; 0];
r_ssmax         = 0;
YZPM            = 0; 
y_zmp           = 0; 
LTR             = 0; 
Vy              = 0;
alphar          = 0;
Roll_Shad       = 0;
Roll_BaknR      = 0;
Station         = 0;
yawrate         = 0;

% CafHat      = 0;
% CarHat      = 0;
% Fyf         = 0;
% Fyr         = 0;
% Arfa_f      = 0;
% Arfa_r      = 0;
    
if InitialGapflag < 2 %  get rid of the first two inputs,  because no data from CarSim
    InitialGapflag = InitialGapflag + 1;
else % start control
    InitialGapflag = InitialGapflag + 1;
%***********Step (2). State estimation and Location **********************% 
    t_Start = tic; % 开始计时  
    %-----Update State Estimation of measured Vehicle Configuration--------%
    [VehStateMeasured, ParaHAT] = func_StateEstimation(u);   
    PosX        = VehStateMeasured.X;
    PosY        = VehStateMeasured.Y;
    PosPsi      = VehStateMeasured.phi;    
    Vel         = VehStateMeasured.x_dot; 
    Vy          = VehStateMeasured.y_dot; 
    yawrate     = VehStateMeasured.phi_dot; % rad/s
    Ax          = VehStateMeasured.Ax; % x_dot
    Ay          = VehStateMeasured.Ay; % y_dot

%     delta_f     = VehStateMeasured.delta_f;% deg-->rad    
    fwa         = VehStateMeasured.fwa;
    Beta        = VehStateMeasured.beta;%rad
    Roll_Shad   = VehStateMeasured.Roll_Shad;%rad
    Station     = VehStateMeasured.Station;
    Roll        = ParaHAT.Roll;
    Rollrate    = ParaHAT.Rollrate;
    Ay_CG       = ParaHAT.Ay_CG;    
    Ay_Bf_SM    = ParaHAT.Ay_Bf_SM;    
    Fyf         = ParaHAT.Fyf;
    Fyr         = ParaHAT.Fyr;   
    alphaf      = ParaHAT.alphaf;
    alphar      = ParaHAT.alphar;
    
    %-----Estimate Cornering stiffness -------------------%  
    %for front tire
    Arfa_f = (Beta + yawrate*VehiclePara.Lf/Vel - fwa);
    [yf, Calpha_f1] = func_RLSFilter_Calpha_f(Arfa_f, Fyf);
    CafHat = sum(Calpha_f1);
    if CafHat > -30000
        CafHat = -110000;
    end
    %for rear tire 
    Arfa_r = (Beta - yawrate*VehiclePara.Lr/Vel);
    [yr, Calpha_r1] = func_RLSFilter_Calpha_r(Arfa_r, Fyr);
    CarHat = sum(Calpha_r1);
    if CarHat > -30000
        CarHat = -92000;
    end    
    %-----OR use constant Cornering stiffness -------------------%  
    CafHat = -90000;
    CarHat = -90000;
    
    %********Step(3): Given reference trajectory, update vehicle state and bounds *******************% 
    [WPIndex, RefP, RefU, Uaug, Uaug_0, PrjP, Roll_BaknR] = func_RefTraj_LocalPlanning_TwoTimeScales_Spatial_Integrated( MPCParameters,... 
                            VehiclePara,... 
                            WayPoints_IndexPre,... 
                            Reftraj.WayPoints_Collect,... 
                            VehStateMeasured ); % 
      y_zmp =  Uaug_0(2);                 
%     Roll_BaknR =  Uaug_0(1);
%     Uaug_0(1) = Roll_Shad;
                            
    if ( WPIndex <= 0)
       fprintf('Error: WPIndex <= 0 \n');    %出错
    else
        Xm = [Vy; yawrate; Rollrate; Roll; PrjP.ey; PrjP.epsi];        
        WayPoints_IndexPre = WPIndex;        
    end

    %****Step(4):  MPC formulation;********************%
%     [StateSpaceModel] = func_RigidbodyDynamicalModel_FOH_Extended(VehiclePara, MPCParameters, Vel, CafHat, CarHat);
    [StateSpaceModel] = func_RigidbodyModel_FOH_Matrix_ROLL(VehiclePara, MPCParameters, Vel, CafHat, CarHat);
    
    Np          = MPCParameters.Np;
    Eymax       = zeros(Np,1);
    Eymin       = zeros(Np,1);     
    LM_right    = -5;
    LM_middle   = 0;
    Yroad_L     = -2.5;
    for i =1:1:Np  % 注意ey是带符号的, Np = 25
        Eymax(i,1) = (LM_middle - Yroad_L);
        Eymin(i,1) = (LM_right - Yroad_L);             
    end
    [Envelope] = func_SafedrivingEnvelope_SL(VehiclePara, MPCParameters, Constraints, StateSpaceModel, Vel, CarHat,  Eymax, Eymin); 
    
    %--- Weighting Regulation functions
    [Sl, Ql, Rdun, Wshl, dun, dul] = func_CostWeightingRegulation_QuadSlacks(MPCParameters, CostWeights, Constraints);

    %================CVXGEN solver==================================%
    settings.verbose    = 0;       % 0-Silence; 1-display
    settings.max_iters  = 25;    %Limits the total iterations
    
    params.x_0      = Xm;
    params.um       = fwa; % measured front whee angle
%     params.x_0      = Xm - 0.6*(Xm - FeedbackCorrects.StatePred);
%     params.um       = fwa - 0.6*(fwa - FeedbackCorrects.Ctrlopt); 
    
    params.As       = StateSpaceModel.As;
    params.Bs1      = StateSpaceModel.Bs1;
    params.Bs2      = StateSpaceModel.Bs2;
    params.Al       = StateSpaceModel.Al;
    params.Bl11     = StateSpaceModel.Bl11;
    params.Bl12     = StateSpaceModel.Bl12;
    params.Bl21     = StateSpaceModel.Bl21;
    params.Bl22     = StateSpaceModel.Bl22;

    params.tstl     = MPCParameters.Ts/MPCParameters.Tsl;
    params.Ql       = Ql;  
    params.Rdun	    = Rdun;  
    params.Wshl	    = Wshl;      
    
    params.dun      = dun; 
    params.dul      = dul; 
    params.umax     = Constraints.umax;    
    params.Sshmax   = Constraints.Sshmax; 
    
    params.Uaug_0   = Uaug_0;
    params.Uaug     = Uaug;
    
    params.Henv     = Envelope.Henv;
    params.Genv     = Envelope.Genv;
    
    params.Hsh      = Envelope.Hsh;
    params.Psh      = Envelope.Psh;
    params.Gsh      = Envelope.Gsh;
 
    params.Hyzmp    = Envelope.H_yzmp;
    params.Pyzmp1   = Envelope.P_yzmp1;
    params.Pyzmp2   = Envelope.P_yzmp2;
    params.Gyzmp    = 1.0; % 0.7; %归一化零力矩点的约束    

    [vars, status] = csolve(params, settings);
    if (1 == status.converged) %if optimization succeeded.
        fwa_opt = vars.u_0; 
%         for i=1:1:20
%             S_opt(i)    = vars.x{i}; 
%             U_opt(i)    = vars.u{i}; 
%         end  
    else
        fwa_opt =  vars.u_0;
        fprintf('CVXGEN converged = 0, InitialGapflag= %d\n', InitialGapflag);                  
    end
    FeedbackCorrects.StatePred = vars.x_1;
    FeedbackCorrects.Ctrlopt   = fwa_opt;    
    %====================================================================%
    Ctrl_SteerSW = 19 * fwa_opt*180/pi; % in deg.    
      
    t_Elapsed = toc( t_Start ); %computation time
    
    %-----------------------------------------%
    e_y            = PrjP.ey;
    e_psi          = PrjP.epsi; 


    Shenvelop_hat  = Envelope.Hsh*Xm + Envelope.Psh*Uaug_0;
    r_ssmax    = Envelope.Gsh(2);

    YZPM = Envelope.H_yzmp*Xm + Envelope.P_yzmp1*fwa_opt + Envelope.P_yzmp2*Uaug_0; % + VehStateMeasured.yawrate_dot*VehiclePara.Iz/(VehiclePara.m*VehiclePara.g);%
    YZPM = 2*YZPM/VehiclePara.Tr;
    
    Fzl = ParaHAT.Fz_l1 + ParaHAT.Fz_l2;
    Fzr = ParaHAT.Fz_r1 + ParaHAT.Fz_r2;
    LTR = (Fzr - Fzl)./(Fzr + Fzl);

    y_zmp  = (Ay_CG)*VehiclePara.hCG/VehiclePara.g + VehiclePara.hCG*(ParaHAT.Roll) - (VehiclePara.Ix)*(ParaHAT.Roll_accel)/(VehiclePara.m*VehiclePara.g);
%     y_zmp  = (Ay_CG)*VehiclePara.hCG/VehiclePara.g + VehiclePara.hCG*(ParaHAT.Roll) - (VehiclePara.Ix)*(ParaHAT.Roll_accel)/(VehiclePara.m*VehiclePara.g); %%%- VehiclePara.hCG*ParaHAT.Roll_accel
% %     y_zmp = ParaHAT.Ay_Bf_SM*ParaHAT.Zcg_SM/VehiclePara.g  + ParaHAT.Zcg_SM.*ParaHAT.Roll - VehiclePara.Ix*(ParaHAT.Roll_accel)/(VehiclePara.m*VehiclePara.g);    
%     y_zmp = 2*y_zmp/VehiclePara.Tr;



     
end % end of if Initialflag < 2 % 

sys = [Ctrl_SteerSW; t_Elapsed; PosX; PosY; PosPsi; Station; Vel; e_psi; e_y; y_zmp; YZPM; LTR; Vy;  alphar; yawrate]; %

%  sys = [Ctrl_SteerSW; CafHat; CarHat; Fyf; Fyr; alphaf; alphar; Arfa_f; Arfa_r];  

% end  %End of mdlOutputs.

%==============================================================
% sub functions
%==============================================================    

%***************************************************************%
% **** State estimation
%***************************************************************%
function [VehStatemeasured, HATParameter] = func_StateEstimation(ModelInput)
%***************************************************************%
% we should do state estimation, but for simplicity we deem that the
% measurements are accurate
% Update the state vector according to the input of the S function,
%           usually do State Estimation from measured Vehicle Configuration
%***************************************************************%  
    %******输入接口转换***%        
    g = 9.81;
    VehStatemeasured.X       = round(100*ModelInput(1))/100;%单位为m, 保留2位小数
    VehStatemeasured.Y       = round(100*ModelInput(2))/100;%单位为m, 保留2位小数    
    VehStatemeasured.phi     = (round(10*ModelInput(3))/10)*pi/180; %航向角,Unit:deg-->rad,保留1位小数    
    VehStatemeasured.x_dot   = ModelInput(4)/3.6; %Unit:km/h-->m/s,保留1位小数  
    VehStatemeasured.y_dot   = ModelInput(5)/3.6; %Unit:km/h-->m/s,保留1位小数   
    VehStatemeasured.phi_dot = (round(10*ModelInput(6))/10)*pi/180; %Unit:deg/s-->rad/s,保留1位小数      
    VehStatemeasured.beta    = (round(10*ModelInput(7))/10)*pi/180;% side slip, Unit:deg-->rad,保留1位小数    
    VehStatemeasured.delta_f = (round(10*0.5*(ModelInput(8)+ ModelInput(9)))/10)*pi/180; % deg-->rad
    VehStatemeasured.fwa     = VehStatemeasured.delta_f * pi/180;  % deg-->rad
    VehStatemeasured.Steer_SW= ModelInput(10); %deg
    VehStatemeasured.Ax      = g*ModelInput(11);%单位为m/s^2, 保留2位小数
    VehStatemeasured.Ay      = g*ModelInput(12);%单位为m/s^2, 保留2位小数
    VehStatemeasured.yawrate_dot = ModelInput(13); %rad/s^2
    % Here I don't explore the state estimation process, and deem the
    % measured values are accurate!!! 
    HATParameter.alpha_l1   = (round(10*ModelInput(14))/10)*pi/180; % deg-->rad,保留1位小数   
    HATParameter.alpha_l2   = (round(10*ModelInput(15))/10)*pi/180; % deg-->rad,保留1位小数   
    HATParameter.alpha_r1   = (round(10*ModelInput(16))/10)*pi/180; % deg-->rad,保留1位小数   
    HATParameter.alpha_r2   = (round(10*ModelInput(17))/10)*pi/180; % deg-->rad,保留1位小数     
    HATParameter.alphaf     = (round(10*0.5 * (ModelInput(14)+ ModelInput(16)))/10)*pi/180; % deg-->rad,保留1位小数   
    HATParameter.alphar     = (round(10*0.5 * (ModelInput(15)+ ModelInput(17)))/10)*pi/180; % deg-->rad,保留1位小数  
    
    HATParameter.Fz_l1      = round(10*ModelInput(18))/10; % N 
    HATParameter.Fz_l2      = round(10*ModelInput(19))/10; % N 
    HATParameter.Fz_r1      = round(10*ModelInput(20))/10; % N 
    HATParameter.Fz_r2      = round(10*ModelInput(21))/10; % N 
    
    HATParameter.Fy_l1      = round(10*ModelInput(22))/10; % N 
    HATParameter.Fy_l2      = round(10*ModelInput(23))/10; % N 
    HATParameter.Fy_r1      = round(10*ModelInput(24))/10; % N 
    HATParameter.Fy_r2      = round(10*ModelInput(25))/10; % N 
    HATParameter.Fyf        = HATParameter.Fy_l1 + HATParameter.Fy_r1;
    HATParameter.Fyr        = HATParameter.Fy_l2 + HATParameter.Fy_r2;
    
    HATParameter.Fx_L1      = ModelInput(26);
    HATParameter.Fx_L2      = ModelInput(27);
    HATParameter.Fx_R1      = ModelInput(28);
    HATParameter.Fx_R2      = ModelInput(29);
    
%     HATParameter.GearStat    = ModelInput(30);
    VehStatemeasured.Roll_Shad   = ModelInput(30)*pi/180;% deg-->rad 
    HATParameter.Roll        = ModelInput(31)*pi/180;% deg-->rad 
    HATParameter.Rollrate    = ModelInput(32)*pi/180;% deg/s-->rad/s
    HATParameter.Roll_accel  = ModelInput(33); % rad/s^2
    HATParameter.Z0          = ModelInput(34); %m
    VehStatemeasured.Station     = ModelInput(35); %m
    HATParameter.Zcg_TM      = ModelInput(35); %m
    HATParameter.Zcg_SM      = ModelInput(36); %m
    HATParameter.Ay_CG       = ModelInput(37)*g; %m/s^2
    HATParameter.Ay_Bf_SM    = ModelInput(38)*g; %m/s^2
    
% end % end of func_StateEstimation

おすすめ

転載: blog.csdn.net/qq_39599752/article/details/127454076