当前位置:   article > 正文

【carsim+simulink 联合仿真——车辆轨迹MPC跟踪】_mpc教程实现车速跟随

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控制车辆运行轨迹

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/920856
推荐阅读
相关标签
  

闽ICP备14008679号