MATLAB Coder:m语言到C++的转换问题与解决

一、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的版本要高一些,感觉大概是这个原因。

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空