• 【carsim+simulink 联合仿真——车辆轨迹MPC跟踪】


    学习北理工的无人驾驶车辆模型预测控制第2版第四章,使用的仿真软件为Carsim8和MatlabR2019a联合仿真,使用MPC控制思想对车辆进行轨迹跟踪控制,并给出仿真结果。

    mpc控制器函数:s-function

    1. function [sys,x0,str,ts] = MY_MPCController3(t,x,u,flag)
    2. % 该函数是写的第3个S函数控制器(MATLAB版本:R2011a)
    3. % 限定于车辆运动学模型,控制量为速度和前轮偏角,使用的QP为新版本的QP解法
    4. % [sys,x0,str,ts] = MY_MPCController3(t,x,u,flag)
    5. %
    6. % is an S-function implementing the MPC controller intended for use
    7. % with Simulink. The argument md, which is the only user supplied
    8. % argument, contains the data structures needed by the controller. The
    9. % input to the S-function block is a vector signal consisting of the
    10. % measured outputs and the reference values for the controlled
    11. % outputs. The output of the S-function block is a vector signal
    12. % consisting of the control variables and the estimated state vector,
    13. % potentially including estimated disturbance states.
    14. switch flag,
    15. case 0
    16. [sys,x0,str,ts] = mdlInitializeSizes; % Initialization
    17. case 2
    18. sys = mdlUpdates(t,x,u); % Update discrete states
    19. case 3
    20. sys = mdlOutputs(t,x,u); % Calculate outputs
    21. case {1,4,9} % Unused flags
    22. sys = [];
    23. otherwise
    24. error(['unhandled flag = ',num2str(flag)]); % Error handling
    25. end
    26. % End of dsfunc.
    27. %==============================================================
    28. % Initialization
    29. %==============================================================
    30. function [sys,x0,str,ts] = mdlInitializeSizes
    31. % Call simsizes for a sizes structure, fill it in, and convert it
    32. % to a sizes array.
    33. sizes = simsizes;
    34. sizes.NumContStates = 0;
    35. sizes.NumDiscStates = 3; % this parameter doesn't matter
    36. sizes.NumOutputs = 2; %[speed, steering]
    37. sizes.NumInputs = 5; %[x,y,yaw,vx,steer_sw]
    38. sizes.DirFeedthrough = 1; % Matrix D is non-empty.
    39. sizes.NumSampleTimes = 1;
    40. sys = simsizes(sizes);
    41. x0 =[0;0;0];
    42. global U; % store current ctrl vector:[vel_m, delta_m]
    43. U=[0;0];
    44. % Initialize the discrete states.
    45. str = []; % Set str to an empty matrix.
    46. ts = [0.05 0]; % sample time: [period, offset]
    47. %End of mdlInitializeSizes
    48. %==============================================================
    49. % Update the discrete states
    50. %==============================================================
    51. function sys = mdlUpdates(t,x,u)
    52. sys = x;
    53. %End of mdlUpdate.
    54. %==============================================================
    55. % Calculate outputs
    56. %==============================================================
    57. function sys = mdlOutputs(t,x,u)
    58. global a b u_piao;
    59. %u_piao矩阵,用于存储每一个仿真时刻,车辆的实际控制量(实际运动状态)与目标控制量(运动状态)之间的偏差
    60. global U; %store chi_tilde=[vel-vel_ref; delta - delta_ref]
    61. global kesi;
    62. tic
    63. Nx=3;%状态量的个数
    64. Nu =2;%控制量的个数
    65. Np =60;%预测步长
    66. Nc=30;%控制步长
    67. Row=10;%松弛因子
    68. fprintf('Update start, t=%6.3f\n',t)
    69. t_d =u(3)*3.1415926/180;%CarSim输出的Yaw angle为角度,角度转换为弧度
    70. % %直线路径
    71. % r(1)=5*t; %ref_x-axis
    72. % r(2)=5;%ref_y-axis
    73. % r(3)=0;%ref_heading_angle
    74. % vd1=5;% ref_velocity
    75. % vd2=0;% ref_steering
    76. % % 半径为25m的圆形轨迹, 圆心为(0, 35), 速度为5m/s
    77. r(1)=25*sin(0.2*t);
    78. r(2)=35-25*cos(0.2*t);
    79. r(3)=0.2*t;
    80. vd1=5;
    81. vd2=0.104;
    82. % %半径为35m的圆形轨迹, 圆心为(0, 35), 速度为3m/s
    83. % r(1)=25*sin(0.12*t);
    84. % r(2)=25+10-25*cos(0.12*t);
    85. % r(3)=0.12*t;
    86. % vd1=3;
    87. % vd2=0.104;
    88. %半径为25m的圆形轨迹, 圆心为(0, 35), 速度为10m/s
    89. % r(1)=25*sin(0.4*t);
    90. % r(2)=25+10-25*cos(0.4*t);
    91. % r(3)=0.4*t;
    92. % vd1=10;
    93. % vd2=0.104;
    94. %半径为25m的圆形轨迹, 圆心为(0, 35), 速度为4m/s
    95. % r(1)=25*sin(0.16*t);
    96. % r(2)=25+10-25*cos(0.16*t);
    97. % r(3)=0.16*t;
    98. % vd1=4;
    99. % vd2=0.104;
    100. % t_d = r(3);
    101. kesi=zeros(Nx+Nu,1);
    102. kesi(1) = u(1)-r(1);%u(1)==X(1),x_offset
    103. kesi(2) = u(2)-r(2);%u(2)==X(2),y_offset
    104. heading_offset = t_d - r(3); %u(3)==X(3),heading_angle_offset
    105. if (heading_offset < -pi)
    106. heading_offset = heading_offset + 2*pi;
    107. end
    108. if (heading_offset > pi)
    109. heading_offset = heading_offset - 2*pi;
    110. end
    111. kesi(3)=heading_offset;
    112. % U(1) = u(4)/3.6 - vd1; % vel, km/h-->m/s
    113. % steer_SW = u(5)*pi/180;
    114. % steering_angle = steer_SW/18.0;
    115. % U(2) = steering_angle - vd2;
    116. kesi(4)=U(1); % vel-vel_ref
    117. kesi(5)=U(2); % steer_angle - steering_ref
    118. fprintf('vel-offset=%4.2f, steering-offset, U(2)=%4.2f\n',U(1), U(2))
    119. T=0.05;
    120. T_all=40;%临时设定,总的仿真时间,主要功能是防止计算期望轨迹越界
    121. % Mobile Robot Parameters
    122. L = 2.6; % wheelbase of carsim vehicle
    123. % Mobile Robot variable
    124. %矩阵初始化
    125. u_piao=zeros(Nx,Nu);
    126. Q=eye(Nx*Np,Nx*Np);
    127. R=5*eye(Nu*Nc);
    128. a=[1 0 -vd1*sin(t_d)*T;
    129. 0 1 vd1*cos(t_d)*T;
    130. 0 0 1;];
    131. b=[cos(t_d)*T 0;
    132. sin(t_d)*T 0;
    133. tan(vd2)*T/L vd1*T/(cos(vd2)^2)];
    134. A_cell=cell(2,2);
    135. B_cell=cell(2,1);
    136. A_cell{1,1}=a;
    137. A_cell{1,2}=b;
    138. A_cell{2,1}=zeros(Nu,Nx);
    139. A_cell{2,2}=eye(Nu);
    140. B_cell{1,1}=b;
    141. B_cell{2,1}=eye(Nu);
    142. A=cell2mat(A_cell);
    143. B=cell2mat(B_cell);
    144. C=[ 1 0 0 0 0;
    145. 0 1 0 0 0;
    146. 0 0 1 0 0];
    147. PHI_cell=cell(Np,1);
    148. THETA_cell=cell(Np,Nc);
    149. for j=1:1:Np
    150. PHI_cell{j,1}=C*A^j;
    151. for k=1:1:Nc
    152. if k<=j
    153. THETA_cell{j,k}=C*A^(j-k)*B;
    154. else
    155. THETA_cell{j,k}=zeros(Nx,Nu);
    156. end
    157. end
    158. end
    159. PHI=cell2mat(PHI_cell);%size(PHI)=[Nx*Np Nx+Nu]
    160. THETA=cell2mat(THETA_cell);%size(THETA)=[Nx*Np Nu*(Nc+1)]
    161. H_cell=cell(2,2);
    162. H_cell{1,1}=THETA'*Q*THETA+R;
    163. H_cell{1,2}=zeros(Nu*Nc,1);
    164. H_cell{2,1}=zeros(1,Nu*Nc);
    165. H_cell{2,2}=Row;
    166. H=cell2mat(H_cell);
    167. % H=(H+H')/2;
    168. error=PHI*kesi;
    169. f_cell=cell(1,2);
    170. f_cell{1,1} = (error'*Q*THETA);
    171. f_cell{1,2} = 0;
    172. f=cell2mat(f_cell);
    173. %% 以下为约束生成区域
    174. %不等式约束
    175. A_t=zeros(Nc,Nc);%见falcone论文 P181
    176. for p=1:1:Nc
    177. for q=1:1:Nc
    178. if q<=p
    179. A_t(p,q)=1;
    180. else
    181. A_t(p,q)=0;
    182. end
    183. end
    184. end
    185. A_I=kron(A_t,eye(Nu));%对应于falcone论文约束处理的矩阵A,求克罗内克积
    186. Ut=kron(ones(Nc,1), U);%
    187. umin=[-0.2; -0.54];%[min_vel, min_steer]维数与控制变量的个数相同
    188. umax=[0.05; 0.436]; %[max_vel, max_steer],%0.436rad = 25deg
    189. delta_umin = [-0.5; -0.0082]; % 0.0082rad = 0.47deg
    190. delta_umax = [0.5; 0.0082];
    191. Umin=kron(ones(Nc,1),umin);
    192. Umax=kron(ones(Nc,1),umax);
    193. A_cons_cell={A_I zeros(Nu*Nc, 1); -A_I zeros(Nu*Nc, 1)};
    194. b_cons_cell={Umax-Ut;-Umin+Ut};
    195. A_cons=cell2mat(A_cons_cell);%(求解方程)状态量不等式约束增益矩阵,转换为绝对值的取值范围
    196. b_cons=cell2mat(b_cons_cell);%(求解方程)状态量不等式约束的取值
    197. % 状态量约束
    198. delta_Umin = kron(ones(Nc,1),delta_umin);
    199. delta_Umax = kron(ones(Nc,1),delta_umax);
    200. lb = [delta_Umin; 0];%(求解方程)状态量下界
    201. ub = [delta_Umax; 10];%(求解方程)状态量上界
    202. %% 开始求解过程
    203. % options = optimset('Algorithm','active-set');
    204. options = optimset('Algorithm','interior-point-convex');
    205. warning off all % close the warnings during computation
    206. [X, fval,exitflag]=quadprog(H, f, A_cons, b_cons,[], [],lb,ub,[],options);
    207. fprintf('quadprog EXITFLAG = %d\n',exitflag);
    208. %% 计算输出
    209. if ~isempty(X)
    210. u_piao(1)=X(1);
    211. u_piao(2)=X(2);
    212. end;
    213. U(1)=kesi(4)+u_piao(1);%用于存储上一个时刻的控制量
    214. U(2)=kesi(5)+u_piao(2);
    215. u_real(1) = U(1) + vd1;
    216. u_real(2) = U(2) + vd2;
    217. sys=u_real % vel, steering, x, y
    218. toc
    219. % End of mdlOutputs.

    新版的matlab没有active-set算法,需要更改为'interior-point-convex',但是会出现X出差索引范围,需要采用旧版的quadprog函数算法,这里更改为quadprog2011,具体代码如下;

    1. function [X,fval,exitflag,output,lambda] = quadprog2011(H,f,A,B,Aeq,Beq,lb,ub,X0,options,varargin)
    2. %QUADPROG Quadratic programming.
    3. % X = QUADPROG(H,f,A,b) attempts to solve the quadratic programming
    4. % problem:
    5. %
    6. % min 0.5*x'*H*x + f'*x subject to: A*x <= b
    7. % x
    8. %
    9. % X = QUADPROG(H,f,A,b,Aeq,beq) solves the problem above while
    10. % additionally satisfying the equality constraints Aeq*x = beq.
    11. %
    12. % X = QUADPROG(H,f,A,b,Aeq,beq,LB,UB) defines a set of lower and upper
    13. % bounds on the design variables, X, so that the solution is in the
    14. % range LB <= X <= UB. Use empty matrices for LB and UB if no bounds
    15. % exist. Set LB(i) = -Inf if X(i) is unbounded below; set UB(i) = Inf if
    16. % X(i) is unbounded above.
    17. %
    18. % X = QUADPROG(H,f,A,b,Aeq,beq,LB,UB,X0) sets the starting point to X0.
    19. %
    20. % X = QUADPROG(H,f,A,b,Aeq,beq,LB,UB,X0,OPTIONS) minimizes with the
    21. % default optimization parameters replaced by values in the structure
    22. % OPTIONS, an argument created with the OPTIMSET function. See OPTIMSET
    23. % for details. Used options are Display, Diagnostics, TolX, TolFun,
    24. % HessMult, LargeScale, MaxIter, PrecondBandWidth, TypicalX, TolPCG, and
    25. % MaxPCGIter. Currently, only 'final' and 'off' are valid values for the
    26. % parameter Display ('iter' is not available).
    27. %
    28. % X = QUADPROG(PROBLEM) finds the minimum for PROBLEM. PROBLEM is a
    29. % structure with matrix 'H' in PROBLEM.H, the vector 'f' in PROBLEM.f,
    30. % the linear inequality constraints in PROBLEM.Aineq and PROBLEM.bineq,
    31. % the linear equality constraints in PROBLEM.Aeq and PROBLEM.beq, the
    32. % lower bounds in PROBLEM.lb, the upper bounds in PROBLEM.ub, the start
    33. % point in PROBLEM.x0, the options structure in PROBLEM.options, and
    34. % solver name 'quadprog' in PROBLEM.solver. Use this syntax to solve at
    35. % the command line a problem exported from OPTIMTOOL. The structure
    36. % PROBLEM must have all the fields.
    37. %
    38. % [X,FVAL] = QUADPROG(H,f,A,b) returns the value of the objective
    39. % function at X: FVAL = 0.5*X'*H*X + f'*X.
    40. %
    41. % [X,FVAL,EXITFLAG] = QUADPROG(H,f,A,b) returns an EXITFLAG that
    42. % describes the exit condition of QUADPROG. Possible values of EXITFLAG
    43. % and the corresponding exit conditions are
    44. %
    45. % All algorithms:
    46. % 1 First order optimality conditions satisfied.
    47. % 0 Maximum number of iterations exceeded.
    48. % -2 No feasible point found.
    49. % -3 Problem is unbounded.
    50. % Interior-point-convex only:
    51. % -6 Non-convex problem detected.
    52. % Trust-region-reflective only:
    53. % 3 Change in objective function too small.
    54. % -4 Current search direction is not a descent direction; no further
    55. % progress can be made.
    56. % Active-set only:
    57. % 4 Local minimizer found.
    58. % -7 Magnitude of search direction became too small; no further
    59. % progress can be made. The problem is ill-posed or badly
    60. % conditioned.
    61. %
    62. % [X,FVAL,EXITFLAG,OUTPUT] = QUADPROG(H,f,A,b) returns a structure
    63. % OUTPUT with the number of iterations taken in OUTPUT.iterations,
    64. % maximum of constraint violations in OUTPUT.constrviolation, the
    65. % type of algorithm used in OUTPUT.algorithm, the number of conjugate
    66. % gradient iterations (if used) in OUTPUT.cgiterations, a measure of
    67. % first order optimality (large-scale algorithm only) in
    68. % OUTPUT.firstorderopt, and the exit message in OUTPUT.message.
    69. %
    70. % [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = QUADPROG(H,f,A,b) returns the set of
    71. % Lagrangian multipliers LAMBDA, at the solution: LAMBDA.ineqlin for the
    72. % linear inequalities A, LAMBDA.eqlin for the linear equalities Aeq,
    73. % LAMBDA.lower for LB, and LAMBDA.upper for UB.
    74. %
    75. % See also LINPROG, LSQLIN.
    76. % Copyright 1990-2010 The MathWorks, Inc.
    77. % $Revision: 1.1.6.14 $ $Date: 2010/11/01 19:41:32 $
    78. defaultopt = struct( ...
    79. 'Algorithm','trust-region-reflective', ...
    80. 'Diagnostics','off', ...
    81. 'Display','final', ...
    82. 'HessMult',[], ...
    83. 'LargeScale','on', ...
    84. 'MaxIter',[], ...
    85. 'MaxPCGIter','max(1,floor(numberOfVariables/2))', ...
    86. 'PrecondBandWidth',0, ...
    87. 'TolCon',1e-8, ...
    88. 'TolFun',[], ...
    89. 'TolPCG',0.1, ...
    90. 'TolX',100*eps, ...
    91. 'TypicalX','ones(numberOfVariables,1)' ...
    92. );
    93. % If just 'defaults' passed in, return the default options in X
    94. if nargin == 1 && nargout <= 1 && isequal(H,'defaults')
    95. X = defaultopt;
    96. return
    97. end
    98. if nargin < 10
    99. options = [];
    100. if nargin < 9
    101. X0 = [];
    102. if nargin < 8
    103. ub = [];
    104. if nargin < 7
    105. lb = [];
    106. if nargin < 6
    107. Beq = [];
    108. if nargin < 5
    109. Aeq = [];
    110. if nargin < 4
    111. B = [];
    112. if nargin < 3
    113. A = [];
    114. end
    115. end
    116. end
    117. end
    118. end
    119. end
    120. end
    121. end
    122. % Detect problem structure input
    123. if nargin == 1
    124. if isa(H,'struct')
    125. [H,f,A,B,Aeq,Beq,lb,ub,X0,options] = separateOptimStruct(H);
    126. else % Single input and non-structure.
    127. error(message('optim:quadprog:InputArg'));
    128. end
    129. end
    130. if nargin == 0
    131. error(message('optim:quadprog:NotEnoughInputs'))
    132. end
    133. % Check for non-double inputs
    134. % SUPERIORFLOAT errors when superior input is neither single nor double;
    135. % We use try-catch to override SUPERIORFLOAT's error message when input
    136. % data type is integer.
    137. try
    138. dataType = superiorfloat(H,f,A,B,Aeq,Beq,lb,ub,X0);
    139. catch ME
    140. if strcmp(ME.identifier,'MATLAB:datatypes:superiorfloat')
    141. dataType = 'notDouble';
    142. end
    143. end
    144. if ~strcmp(dataType,'double')
    145. error(message('optim:quadprog:NonDoubleInput'))
    146. end
    147. % Set up constant strings
    148. activeSet = 'active-set';
    149. trustRegReflect = 'trust-region-reflective';
    150. interiorPointConvex = 'interior-point-convex';
    151. if nargout > 4
    152. computeLambda = true;
    153. else
    154. computeLambda = false;
    155. end
    156. if nargout > 3
    157. computeConstrViolation = true;
    158. computeFirstOrderOpt = true;
    159. else
    160. computeConstrViolation = false;
    161. computeFirstOrderOpt = false;
    162. end
    163. % Options setup
    164. largescale = isequal(optimget(options,'LargeScale',defaultopt,'fast'),'on');
    165. Algorithm = optimget(options,'Algorithm',defaultopt,'fast');
    166. diagnostics = isequal(optimget(options,'Diagnostics',defaultopt,'fast'),'on');
    167. display = optimget(options,'Display',defaultopt,'fast');
    168. detailedExitMsg = ~isempty(strfind(display,'detailed'));
    169. switch display
    170. case {'off', 'none'}
    171. verbosity = 0;
    172. case {'iter','iter-detailed'}
    173. verbosity = 2;
    174. case {'final','final-detailed'}
    175. verbosity = 1;
    176. case 'testing'
    177. verbosity = 3;
    178. otherwise
    179. verbosity = 1;
    180. end
    181. % Determine algorithm user chose via options. (We need this now to set
    182. % OUTPUT.algorithm in case of early termination due to inconsistent
    183. % bounds.) This algorithm choice may be modified later when we check the
    184. % problem type.
    185. algChoiceOptsConflict = false;
    186. if strcmpi(Algorithm,'active-set')
    187. output.algorithm = activeSet;
    188. elseif strcmpi(Algorithm,'interior-point-convex')
    189. output.algorithm = interiorPointConvex;
    190. elseif strcmpi(Algorithm,'trust-region-reflective')
    191. if largescale
    192. output.algorithm = trustRegReflect;
    193. else
    194. % Conflicting options Algorithm='trust-region-reflective' and
    195. % LargeScale='off'. Choose active-set algorithm.
    196. algChoiceOptsConflict = true; % Warn later, not in case of early termination
    197. output.algorithm = activeSet;
    198. end
    199. else
    200. error(message('optim:quadprog:InvalidAlgorithm'));
    201. end
    202. mtxmpy = optimget(options,'HessMult',defaultopt,'fast');
    203. % Check for name clash
    204. functionNameClashCheck('HessMult',mtxmpy,'hessMult_optimInternal','optim:quadprog:HessMultNameClash');
    205. if isempty(mtxmpy)
    206. % Internal Hessian-multiply function
    207. mtxmpy = @hessMult_optimInternal;
    208. usrSuppliedHessMult = false;
    209. else
    210. usrSuppliedHessMult = true;
    211. end
    212. % Set the constraints up: defaults and check size
    213. [nineqcstr,numberOfVariablesineq] = size(A);
    214. [neqcstr,numberOfVariableseq] = size(Aeq);
    215. if isa(H,'double') && ~usrSuppliedHessMult
    216. % H must be square and have the correct size
    217. nColsH = size(H,2);
    218. if nColsH ~= size(H,1)
    219. error(message('optim:quadprog:NonSquareHessian'));
    220. end
    221. else % HessMult in effect, so H can be anything
    222. nColsH = 0;
    223. end
    224. % Check the number of variables. The check must account for any combination of these cases:
    225. % * User provides HessMult
    226. % * The problem is linear (H = zeros, or H = [])
    227. % * The objective has no linear component (f = [])
    228. % * There are no linear constraints (A,Aeq = [])
    229. % * There are no, or partially specified, bounds
    230. % * There is no X0
    231. numberOfVariables = ...
    232. max([length(f),nColsH,numberOfVariablesineq,numberOfVariableseq]);
    233. if numberOfVariables == 0
    234. % If none of the problem quantities indicate the number of variables,
    235. % check X0, even though some algorithms do not use it.
    236. if isempty(X0)
    237. error(message('optim:quadprog:EmptyProblem'));
    238. else
    239. % With all other data empty, use the X0 input to determine
    240. % the number of variables.
    241. numberOfVariables = length(X0);
    242. end
    243. end
    244. ncstr = nineqcstr + neqcstr;
    245. if isempty(f)
    246. f = zeros(numberOfVariables,1);
    247. else
    248. % Make sure that the number of rows/columns in H matches the length of
    249. % f under the following conditions:
    250. % * The Hessian is passed in explicitly (no HessMult)
    251. % * There is a non-empty Hessian
    252. if ~usrSuppliedHessMult && ~isempty(H)
    253. if length(f) ~= nColsH
    254. error(message('optim:quadprog:MismatchObjCoefSize'));
    255. end
    256. end
    257. end
    258. if isempty(A)
    259. A = zeros(0,numberOfVariables);
    260. end
    261. if isempty(B)
    262. B = zeros(0,1);
    263. end
    264. if isempty(Aeq)
    265. Aeq = zeros(0,numberOfVariables);
    266. end
    267. if isempty(Beq)
    268. Beq = zeros(0,1);
    269. end
    270. % Expect vectors
    271. f = f(:);
    272. B = B(:);
    273. Beq = Beq(:);
    274. if ~isequal(length(B),nineqcstr)
    275. error(message('optim:quadprog:InvalidSizesOfAAndB'))
    276. elseif ~isequal(length(Beq),neqcstr)
    277. error(message('optim:quadprog:InvalidSizesOfAeqAndBeq'))
    278. elseif ~isequal(length(f),numberOfVariablesineq) && ~isempty(A)
    279. error(message('optim:quadprog:InvalidSizesOfAAndF'))
    280. elseif ~isequal(length(f),numberOfVariableseq) && ~isempty(Aeq)
    281. error(message('optim:quadprog:InvalidSizesOfAeqAndf'))
    282. end
    283. [X0,lb,ub,msg] = checkbounds(X0,lb,ub,numberOfVariables);
    284. if ~isempty(msg)
    285. exitflag = -2;
    286. X=X0; fval = []; lambda = [];
    287. output.iterations = 0;
    288. output.constrviolation = [];
    289. output.algorithm = ''; % Not known at this stage
    290. output.firstorderopt = [];
    291. output.cgiterations = [];
    292. output.message = msg;
    293. if verbosity > 0
    294. disp(msg)
    295. end
    296. return
    297. end
    298. % Check that all data is real
    299. if ~(isreal(H) && isreal(A) && isreal(Aeq) && isreal(f) && ...
    300. isreal(B) && isreal(Beq) && isreal(lb) && isreal(ub) && isreal(X0))
    301. error(message('optim:quadprog:ComplexData'))
    302. end
    303. caller = 'quadprog';
    304. % Check out H and make sure it isn't empty or all zeros
    305. if isa(H,'double') && ~usrSuppliedHessMult
    306. if norm(H,'inf')==0 || isempty(H)
    307. % Really a lp problem
    308. warning(message('optim:quadprog:NullHessian'))
    309. [X,fval,exitflag,output,lambda]=linprog(f,A,B,Aeq,Beq,lb,ub,X0,options);
    310. return
    311. else
    312. % Make sure it is symmetric
    313. if norm(H-H',inf) > eps
    314. if verbosity > -1
    315. warning(message('optim:quadprog:HessianNotSym'))
    316. end
    317. H = (H+H')*0.5;
    318. end
    319. end
    320. end
    321. % Determine which algorithm and make sure problem matches.
    322. hasIneqs = (nineqcstr > 0); % Does the problem have any inequalities?
    323. hasEqsAndBnds = (neqcstr > 0) && (any(isfinite(ub)) || any(isfinite(lb))); % Does the problem have both equalities and bounds?
    324. hasMoreEqsThanVars = (neqcstr > numberOfVariables); % Does the problem have more equalities than variables?
    325. hasNoConstrs = (neqcstr == 0) && (nineqcstr == 0) && ...
    326. all(eq(ub, inf)) && all(eq(lb, -inf)); % Does the problem not have equalities, bounds, or inequalities?
    327. if (hasIneqs || hasEqsAndBnds || hasMoreEqsThanVars || hasNoConstrs) && ...
    328. strcmpi(output.algorithm,trustRegReflect) || strcmpi(output.algorithm,activeSet)
    329. % (has linear inequalites OR both equalities and bounds OR has no constraints OR
    330. % has more equalities than variables) then call active-set code
    331. if algChoiceOptsConflict
    332. % Active-set algorithm chosen as a result of conflicting options
    333. warning('optim:quadprog:QPAlgLargeScaleConflict', ...
    334. ['Options LargeScale = ''off'' and Algorithm = ''trust-region-reflective'' conflict. ' ...
    335. 'Ignoring Algorithm and running active-set algorithm. To run trust-region-reflective, set ' ...
    336. 'LargeScale = ''on''. To run active-set without this warning, set Algorithm = ''active-set''.']);
    337. end
    338. if strcmpi(output.algorithm,trustRegReflect)
    339. warning('optim:quadprog:SwitchToMedScale', ...
    340. ['Trust-region-reflective algorithm does not solve this type of problem, ' ...
    341. 'using active-set algorithm. You could also try the interior-point-convex ' ...
    342. 'algorithm: set the Algorithm option to ''interior-point-convex'' ', ...
    343. 'and rerun. For more help, see %s in the documentation.'], ...
    344. addLink('Choosing the Algorithm','choose_algorithm'))
    345. end
    346. output.algorithm = activeSet;
    347. Algorithm = 'active-set';
    348. if issparse(H) || issparse(A) || issparse(Aeq) % Passed in sparse matrices
    349. warning(message('optim:quadprog:ConvertingToFull'))
    350. end
    351. H = full(H); A = full(A); Aeq = full(Aeq);
    352. else
    353. % Using trust-region-reflective or interior-point-convex algorithms
    354. if ~usrSuppliedHessMult
    355. H = sparse(H);
    356. end
    357. A = sparse(A); Aeq = sparse(Aeq);
    358. end
    359. if ~isa(H,'double') || usrSuppliedHessMult && ...
    360. ~strcmpi(output.algorithm,trustRegReflect)
    361. error(message('optim:quadprog:NoHessMult', Algorithm))
    362. end
    363. if diagnostics
    364. % Do diagnostics on information so far
    365. gradflag = []; hessflag = []; line_search=[];
    366. constflag = 0; gradconstflag = 0; non_eq=0;non_ineq=0;
    367. lin_eq=size(Aeq,1); lin_ineq=size(A,1); XOUT=ones(numberOfVariables,1);
    368. funfcn{1} = [];ff=[]; GRAD=[];HESS=[];
    369. confcn{1}=[];c=[];ceq=[];cGRAD=[];ceqGRAD=[];
    370. msg = diagnose('quadprog',output,gradflag,hessflag,constflag,gradconstflag,...
    371. line_search,options,defaultopt,XOUT,non_eq,...
    372. non_ineq,lin_eq,lin_ineq,lb,ub,funfcn,confcn,ff,GRAD,HESS,c,ceq,cGRAD,ceqGRAD);
    373. end
    374. % Trust-region-reflective
    375. if strcmpi(output.algorithm,trustRegReflect)
    376. % Call sqpmin when just bounds or just equalities
    377. [X,fval,output,exitflag,lambda] = sqpmin(f,H,mtxmpy,X0,Aeq,Beq,lb,ub,verbosity, ...
    378. options,defaultopt,computeLambda,computeConstrViolation,varargin{:});
    379. if exitflag == -10 % Problem not handled by sqpmin at this time: dependent rows
    380. warning(message('optim:quadprog:SwitchToMedScale'))
    381. output.algorithm = activeSet;
    382. if ~isa(H,'double') || usrSuppliedHessMult
    383. error('optim:quadprog:NoHessMult', ...
    384. 'H must be specified explicitly for active-set algorithm: cannot use HessMult option.')
    385. end
    386. H = full(H); A = full(A); Aeq = full(Aeq);
    387. end
    388. end
    389. % Call active-set algorithm
    390. if strcmpi(output.algorithm,activeSet)
    391. if isempty(X0)
    392. X0 = zeros(numberOfVariables,1);
    393. end
    394. % Set default value of MaxIter for qpsub
    395. defaultopt.MaxIter = 200;
    396. % Create options structure for qpsub
    397. qpoptions.MaxIter = optimget(options,'MaxIter',defaultopt,'fast');
    398. % A fixed constraint tolerance (eps) is used for constraint
    399. % satisfaction; no need to specify any value
    400. qpoptions.TolCon = [];
    401. [X,lambdaqp,exitflag,output,~,~,msg]= ...
    402. qpsub(H,f,[Aeq;A],[Beq;B],lb,ub,X0,neqcstr,...
    403. verbosity,caller,ncstr,numberOfVariables,qpoptions);
    404. output.algorithm = activeSet; % have to reset since call to qpsub obliterates
    405. end
    406. if strcmpi(output.algorithm,interiorPointConvex)
    407. defaultopt.MaxIter = 200;
    408. defaultopt.TolFun = 1e-8;
    409. % If the output structure is requested, we must reconstruct the
    410. % Lagrange multipliers in the postsolve. Therefore, set computeLambda
    411. % to true if the output structure is requested.
    412. flags.computeLambda = computeFirstOrderOpt;
    413. flags.detailedExitMsg = detailedExitMsg;
    414. flags.verbosity = verbosity;
    415. [X,fval,exitflag,output,lambda] = ipqpcommon(H,f,A,B,Aeq,Beq,lb,ub,X0, ...
    416. flags,options,defaultopt,varargin{:});
    417. % Presolve may have removed variables and constraints from the problem.
    418. % Postsolve will re-insert the primal and dual solutions after the main
    419. % algorithm has run. Therefore, constraint violation and first-order
    420. % optimality must be re-computed.
    421. %
    422. % If no initial point was provided by the user and the presolve has
    423. % declared the problem infeasible or unbounded, X will be empty. The
    424. % lambda structure will also be empty, so do not compute constraint
    425. % violation or first-order optimality if lambda is missing.
    426. % Compute constraint violation if the output structure is requested
    427. if computeFirstOrderOpt && ~isempty(lambda)
    428. output.constrviolation = norm([Aeq*X-Beq; max([A*X - B;X - ub;lb - X],0)],Inf);
    429. end
    430. end
    431. % Compute fval and first-order optimality if the active-set algorithm was
    432. % run, or if the interior-point-convex algorithm was run (not stopped in presolve)
    433. if (strcmpi(output.algorithm,interiorPointConvex) && ~isempty(lambda)) || ...
    434. strcmpi(output.algorithm,activeSet)
    435. % Compute objective function value
    436. fval = 0.5*X'*(H*X)+f'*X;
    437. % Compute lambda and exit message for active-set algorithm
    438. if strcmpi(output.algorithm,activeSet)
    439. if computeLambda || computeFirstOrderOpt
    440. llb = length(lb);
    441. lub = length(ub);
    442. lambda.lower = zeros(llb,1);
    443. lambda.upper = zeros(lub,1);
    444. arglb = ~isinf(lb); lenarglb = nnz(arglb);
    445. argub = ~isinf(ub); lenargub = nnz(argub);
    446. lambda.eqlin = lambdaqp(1:neqcstr,1);
    447. lambda.ineqlin = lambdaqp(neqcstr+1:neqcstr+nineqcstr,1);
    448. lambda.lower(arglb) = lambdaqp(neqcstr+nineqcstr+1:neqcstr+nineqcstr+lenarglb);
    449. lambda.upper(argub) = lambdaqp(neqcstr+nineqcstr+lenarglb+1: ...
    450. neqcstr+nineqcstr+lenarglb+lenargub);
    451. end
    452. if exitflag == 1
    453. normalTerminationMsg = sprintf('Optimization terminated.');
    454. if verbosity > 0
    455. disp(normalTerminationMsg)
    456. end
    457. if isempty(msg)
    458. output.message = normalTerminationMsg;
    459. else
    460. % append normal termination msg to current output msg
    461. output.message = sprintf('%s\n%s',msg,normalTerminationMsg);
    462. end
    463. else
    464. output.message = msg;
    465. end
    466. end
    467. % Compute first order optimality if needed
    468. if computeFirstOrderOpt && ~isempty(lambda)
    469. output.firstorderopt = computeKKTErrorForQPLP(H,f,A,B,Aeq,Beq,lb,ub,lambda,X);
    470. else
    471. output.firstorderopt = [];
    472. end
    473. output.cgiterations = [];
    474. end

    结果:绿线为目标轨迹,红虚线为mpc控制车辆运行轨迹

  • 相关阅读:
    Python实现的热点话题发现系统
    GaussDB拿下的安全认证CC EAL4+究竟有多难?
    windows下载虚拟机virtualBox
    解析java中的String类中的常用方法(二)
    MIGraphX推理框架第十章-MIGraphX常见问题
    Mendeley在linux中无法打开APPimage
    高通SDX12:SFE(shortcut-fe)软加速驱动效果调测
    HarmonyOS应用开发-AnimationDemo体验分享
    PhaGCN2:病毒聚类
    输电线路AR可视化巡检降低作业风险
  • 原文地址:https://blog.csdn.net/qq_31329259/article/details/126517157