概述
目录
一、MATLAB Coder的使用步骤:
二、遇到的问题
三、Matlab版本问题
一、MATLAB Coder的使用步骤:
在命令行窗口输入
>>coder
建议: 在定义 (一维) 变量数组的数据类型及大小时,建议定义为 double(1 × :inf),避免在数组运算过程中由于引入新的定义的中间变量数组,导致数组计算的等式左右两端数组大小不对等
下一步,
②: 在点击“Generate”后也存在许多报错,需要按照提示修改函数.m代码
下面列出一些我遇到是问题及解决方案:
二、遇到的问题
1.以我的部分代码(自定义的MPC函数中调用quadprog函数求解)为例:
......
%新的A,B,C矩阵
A_cell = cell(2,2);
B_cell = cell(2,1);
A_cell{1,1} = a;
A_cell{1,2} = b;
A_cell{2,1} = zeros(Nu,Nx);
A_cell{2,2} = eye(Nu);
B_cell{1,1} = b;
B_cell{2,1} = eye(Nu);
A = cell2mat(A_cell);
B = cell2mat(B_cell);
C = [eye(Nx), zeros(Nx,Nu)];
%PHI矩阵及THETA矩阵
PHI_cell = cell(Np,1);
THETA_cell = cell(Np,Nc);
for j = 1:1:Np
PHI_cell{j,1} = C*A^j;%cell的引用必须用大括号{},否则被看做double类型
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);%矩阵左上角均为0
end
end
end
PHI = cell2mat(PHI_cell);%size(PHI) = [Nx*Np Nx+Nu]
THETA = cell2mat(THETA_cell);%size(THETA) = [Nx*Np Nu*(Nc+1)]
%%二次型目标函数的相关矩阵
H_cell = cell(2,2);
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;%row松弛因子,为了能够得到最优解,防止出现无解的情况
H = cell2mat(H_cell);
%误差E矩阵
E = PHI*kesi;%预测时域内的跟踪误差
%g矩阵
g_cell = cell(1,2);
g_cell{1,1} = 2*E'*Q*THETA;
g_cell{1,2} = 0;
g = cell2mat(g_cell);
%%约束条件的相关矩阵
%A_I矩阵
A_t = zeros(Nc,Nc); %下三角矩阵
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矩阵
Ut = kron(ones(Nc,1),U);
%控制量和控制量变化量的约束
Umin = kron(ones(Nc,1),u_min);
Umax = kron(ones(Nc,1),u_max);
delta_Umin = kron(ones(Nc,1),delta_min);
delta_Umax = kron(ones(Nc,1),delta_max);
%用于quadprog函数不等式约束Ax<=b的矩阵A和向量b
A_cons_cell = {A_I zeros(Nu*Nc,1);-A_I zeros(Nu*Nc,1)}; %为了和H的列数匹配,新添加一列0
b_cons_cell = {Umax - Ut;-Umin+Ut};
A_cons = cell2mat(A_cons_cell);
b_cons = cell2mat(b_cons_cell);
%△U的上下边界
lb = [delta_Umin;0];%;(求解方程)状态量下界,包含控制时域内控制增量和松弛因子
ub = [delta_Umax;10];%;(求解方程)状态量上界,包含控制时域内控制增量和松弛因子
%开始求解过程
options = optimset('Algorithm','interior-point-convex');
%↑内点法求解二次规划问题
delta_U = quadprog(H,g,A_cons,b_cons,[],[],lb,ub,[],options);
编译代码时 遇到“‘cell2mat’及'quadprog' ‘optimset’is not supported for code generation”的问题,这是因为MATLAB自己封装的函数是不支持C++代码生成的,需要将其定义为外部函数,即使用coder.extrinsic声明一下。并且:
参考Generate Code for quadprog- MATLAB & Simulink- MathWorks 中国
将函数optimset 改为 optimoptions:
2.编译代码时 遇到“Expected either a logical, char, int, fi, single, or double. Found an mxArray. MxArrays are returnedfrom calls to the MATLAB interpreter and are not supported inside expressions. They may only beused on the right-hand side of assignments and as arguments to extrinsic functions.”
这是因为在编译过程中,编译器将函数的求解值(这里是delta_U)定义为mxArray类型,mxArray类型的变量只能放在等式的右边,不能被赋值(赋值都是double类型的数值,不等同)。因此,初始化被赋为mxArray的变量,初始化之后系统将其划定为double类型,就可以进行运算了:
3.“cell2mat”和“quadprog”不能被生成C++
在网上看到了关于quadprog的解释:
因此,将所有的cell转化为固定大小的mat类型 ;另外,将quadprog函数注释掉了,目前没有解决quadprog的C++表示问题。(目前还在学习阶段,希望能够得到大神的解答!!)
修改后的代码为:
A = zeros(5);
B = zeros(5,2);%在编译生成代码时,cell类型不适用,只能用已知大小的数值矩阵
%新的A,B,C矩阵
A(1:3,1:3) = a;
A(1:3,4:5) = b;
A(4:5,4:5) = eye(Nu);
B(1:3,:)= b;
B(4:5,:) = eye(Nu);
C = [eye(Nx), zeros(Nx,Nu)];
%PHI矩阵及THETA矩阵
% PHI_cell = cell(Np,1);
% THETA_cell = cell(Np,Nc);
PHI = zeros(Np*Nx,5);
THETA = zeros(Np*Nx,Nc*Nu);
for j = 1:1:Np
PHI((j*Nx-(Nx-1)):j*Nx,1:5) = C*A^j;%cell的引用必须用大括号{},否则被看做double类型
for k = 1:1:Nc
if k<=j
THETA((j*Nx-(Nx-1)):j*Nx,(k*Nu-(Nu-1)):k*Nu) = C*A^(j-k)*B;%左下角矩阵填充
else
THETA((j*Nx-(Nx-1)):j*Nx,(k*Nu-(Nu-1)):k*Nu) = zeros(Nx,Nu);%矩阵左上角均为0
end
end
end
%%二次型目标函数的相关矩阵
H = zeros(61);
H(1:60,1:60)= THETA'*Q*THETA + R;
H(1:60,61) = zeros(Nu*Nc,1);
H(61,1:60) = zeros(1,Nu*Nc);
H(61,61) = row;%row松弛因子,为了能够得到最优解,防止出现无解的情况
%误差E矩阵
E = PHI*kesi;%预测时域内的跟踪误差
%g矩阵
g = zeros(1,61);
g(1:60) = 2*E'*Q*THETA;
g(61) = 0;
%%约束条件的相关矩阵
%A_I矩阵
A_t = zeros(Nc,Nc); %下三角矩阵
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矩阵
Ut = kron(ones(Nc,1),U);
%控制量和控制量变化量的约束
Umin = kron(ones(Nc,1),u_min);
Umax = kron(ones(Nc,1),u_max);
delta_Umin = kron(ones(Nc,1),delta_min);
delta_Umax = kron(ones(Nc,1),delta_max);
%用于quadprog函数不等式约束Ax<=b的矩阵A和向量b
A_cons = zeros(Nu*Nc*2,Nu*Nc+1);
A_cons(1:Nu*Nc,1:Nu*Nc) = A_I;
A_cons((Nu*Nc+1):(2*Nu*Nc), (Nu*Nc+1):(2*Nu*Nc)) = -A_I;
b_cons = zeros(Nu*Nc*2,1);
b_cons(1:Nu*Nc,1) = Umax - Ut;
b_cons((Nu*Nc+1):(2*Nu*Nc),1) = -Umin+Ut;
%△U的上下边界
lb = [delta_Umin;0];%;(求解方程)状态量下界,包含控制时域内控制增量和松弛因子
ub = [delta_Umax;10];%;(求解方程)状态量上界,包含控制时域内控制增量和松弛因子
coder.extrinsic('optimoptions');
coder.extrinsic('quadprog');
%开始求解过程
% options = optimoptions('quadprog','Algorithm','interior-point-convex' );
% %options = optimoptions('quadprog','MaxIterations',100);%有效集法求解二次规划问题目前已经没有
% %↑内点法求解二次规划问题
% delta_U = quadprog(H,g,A_cons,b_cons,[],[],lb,ub,[],options);
三、Matlab版本问题
建议:Matlab的版本要高一点(至少要比Visual Studio的版本高),我在之前Matlab 和VS都是2019版本,可是按照【详细记录】Visual Studio 2019+matlab2017b mex无法正常使用,找不到已安装的编译器_老子姓李!的博客-CSDN博客_matlab visual文章进行MATLAB和Visual Studio的环境配置及验证,在命令行窗口输入
>>mex -setup C++
显示
“找到已安装的编译器 'Microsoft Visual C++ 2019 (C)'。
MEX 配置为使用 'Microsoft Visual C++ 2019 (C)' 以进行 C 语言编译。”
但是在MATLAB Coder生成代码时不能成功,显示“??? The extrinsic function 'ce112mat' is not available for standalone code generation.”:
但是由上面我们已知:有些函数虽然是不支持内部代码生成的,但将其定义为外部函数,使用coder.extrinsic声明一下即可通过编译,为什么会在生成代码的时候报错呢?
后来下载了MATLAB 2022a版本,在生成代码时没有报错,看到很多文章说Matlab的版本要高一些,感觉大概是这个原因。
最后
以上就是体贴芹菜为你收集整理的使用MATLAB Coder Generation将m语言转化为C++过程遇到的问题及解决一、MATLAB Coder的使用步骤: 二、遇到的问题三、Matlab版本问题的全部内容,希望文章能够帮你解决使用MATLAB Coder Generation将m语言转化为C++过程遇到的问题及解决一、MATLAB Coder的使用步骤: 二、遇到的问题三、Matlab版本问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复