我是靠谱客的博主 体贴芹菜,最近开发中收集的这篇文章主要介绍使用MATLAB Coder Generation将m语言转化为C++过程遇到的问题及解决一、MATLAB Coder的使用步骤: 二、遇到的问题三、Matlab版本问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

一、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版本问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部