VS2017的C#语言与matlab2014A的m语言混合编程的方法

本文探讨了在C#中调用MATLAB代码的两种方法:直接通过MATLAB应用类型库执行.m文件和将MATLAB函数编译为DLL库。直接调用方法简单易用,但需要MATLAB环境,适合开发;而库函数方法便于部署,只需MATLAB编译运行时组件MCR。项目实例展示了这两种方法的具体步骤和优缺点。
摘要由CSDN通过智能技术生成

VS2017的C#语言与matlab2014A的m语言混合编程的方法


摘要: 有两种方法能够实现C#语言调用matlab编写的函数:一种是利用matlab应用类型库直接调用matlab函数;另一种是将matlab函数编译成库函数,调用库函数。本文通过计算机器人质量质心的项目实例叙述了这两种方法的实现步骤,并对所用到的两种语言之间常用的变量转换方法进行了讲解,最后总结了这两种方法的优缺点。

关键词: C#, matlab, 混合编程,动态链接库

matlab语言与C#语言

matlab语言是解释型语言,它封装了C/C++语言,易学易用,而且非常适合与做矩阵运算,解微分方程、常微分方程,图像处理等科学计算。 但matlab程序运行时边解释边执行,因此执行效率较低。 C#语言是面向对象的编译执行语言,程序执行时需要先编译成目标代码,然后执行整个目标代码,因此执行效率较高;C#语言基于微软的.NET 框架,已被广泛地应用于编写计算机通讯和网络应用程序中。

软件项目开发中经常会遇到这样一种情况:项目用C#语言编写应用程序,在应用程序中需要利用一些复杂的算法,这些算法用matlab语言编写和验证比较方便快捷。 因此,需要将matlab语言编写的算法集成在C#语言编写的应用程序中,利用C#语言调用matlab函数模块。

C#语言调用matlab语言的两种方法

有两种方法可将matlab语言应用在C#程序中,一种是在C#项目中引用matlab应用类型库Matlab Application Type Library, 通过MLApp.MLApp类对象的方法 Excute() 调用matlab的函数;

另一种方法是通过matlab的部署工具deploytool将matlab编译成动态链接库*.dll, 在C#项目中引用库,若库中还用到了matlab的其他组件,还要在运行C#的计算机上安装matlab编译运行时组件MCR.

本文通过项目实例介绍这两种方法的具体实施及优缺点。首先介绍matalb实现机器人质量质心的算法,算法中用到了通过矩阵的QR分解获得矩阵的特征值,解线性方程组最优解,获得工具测质量、质心的X,Y,Z坐标值;接着通过例程讲解了如何实现C#代码直接调用matlab语言和C#间接调用matlab语言编译的动态链接库的两种方法,并分析了这两种方法的优缺点。

项目实例的界面效果如下:
人机界面图

实现机器人工具质量质心的计算的matlab代码

工具质量质心计算部分采用matlab编写的.m文件,文件位于./calibration/目录,如下图所示:
所用到的matlab文件

其中, test_mass_calibration.m为测试文件,用于随机输入一些数据测试质量质心;而realtime_mass_calibration.m为实际部署到项目中的文件,用于将实际测试到的关节位置下的工具的力和力矩值输入到计算模块中。

VS项目中直接执行matlab语言

1. C#项目中直接调用matlab语言分以下几个步骤:

  1. 在项目中引用matlab应用类型库, 点击 项目 – 右键引用 – 添加引用 – COM ,选择Matlab Application (Version 9.7) Type Library(MLApp).
    在VS项目中添加引用

  2. 在双击左边的运行按钮对应的成员函数中,利用MLApp.MLApp类的Execute()函数,直接调用matlab语句或函数, 代码如下:

     #region 建立matlab工作环境
     string path_project = Directory.GetCurrentDirectory();   //工程文件的路径,如bin/debug/
     string path_matlab = "cd('" + path_project + "/../../../../../calibration')";     //自定义matlab工作路径    这里我注释调用 
     MLApp.MLApp matlab = null;
     Type matlabAppType = System.Type.GetTypeFromProgID("Matlab.Application");
     matlab = System.Activator.CreateInstance(matlabAppType) as MLApp.MLApp;
     matlab.Execute(path_matlab); //进入matlab函数所在的目录
     #endregion
    
     #region 运行matlab程序
     matlab.Execute(@"[mass] = test_mass_calibration();");
     matlab.Execute("MASS = mass.mass;");
     matlab.Execute("P_EE_CM_X =mass.p_ee_cm(1,1); ");
     matlab.Execute("P_EE_CM_Y =mass.p_ee_cm(2,1); ");
     matlab.Execute("P_EE_CM_Z =mass.p_ee_cm(3,1); ");
     matlab.Execute("ERROR_STATUS = mass.error_status;");
     object mass = null;
     object p_ee_cm_x = null;
     object p_ee_cm_y = null;
     object p_ee_cm_z = null;
     object error_status = null;
     try
     {
      	matlab.GetWorkspaceData("ERROR_STATUS", "base", out error_status);
      	matlab.GetWorkspaceData("MASS", "base", out mass);
      	matlab.GetWorkspaceData("P_EE_CM_X", "base", out p_ee_cm_x);
      	matlab.GetWorkspaceData("P_EE_CM_Y", "base", out p_ee_cm_y);
      	matlab.GetWorkspaceData("P_EE_CM_Z", "base", out p_ee_cm_z);
      	//赋值
      	this.MassBySentence = (double)mass;
      	this.BaryCenterBySentenceX = (double)p_ee_cm_x;
      	this.BaryCenterBySentenceY = (double)p_ee_cm_y;
      	this.BaryCenterBySentenceZ = (double)p_ee_cm_z;
     }
     catch (Exception)
     {
      	throw;
     }
     if ((double)error_status == 1)
      	MessageBox.Show("工具质量质心测试失败,请改变末端工具的位置姿态");
     #endregion
    

2. 这种方法主要应用的MLApp.MLApp类的以下几个成员函数:

  1. 直接调用matlab语句或函数

     matlab.Execute("cd('" + path_project + "/../../../../../calibration')");
    
  2. 从matlab的workpace中获得object计算结果;

     object mass = null;		
     matlab.GetWorkspaceData("MASS", "base", out mass);
     this.MassBySentence = (double)mass;
    
  3. 将变量传输到matlab的workspace中;

     matlab.PutWorkspaceData("gam", "base", gam);
    

3. 优缺点

在C#项目中引用matlab应用类型库MLApp,通过MLApp.MLApp类对象的方法Excute直接调用matlab函数. 这种方法的优点是在C#项目中直接调用**.m**文件的函数,直观易用,开发效率高。缺点是要求在运行调试C#项目的计算机上必须同时安装有Visual Studio和matlab,显然这种方法只能用于科学研究,对于最终产品是不适合的,你总不能在用户购买你的软件产品的同时,还要再购买matlab软件吧。

VS项目中调用matlab编译生成的库函数

1. C#项目中调用matlab编译生成的库函数的步骤

1. 在matlab工具上编译.m函数文件成库文件。

我所用的matlab版本号为matlab1014A, 首先在matlab上检查需要编译的.m函数文件没有语法错误和运算错误,之后在命令行窗口输入deploytool,
选择Library Compiler

选择Library Compiler, 进入编译界面
matlab编译页面

2. Library Compiler窗口各个变量的设置

在TYPE窗口,选择.NET Assembly; 在EXPORTED FUNCTIONS窗口,添加.m函数文件,注意只能添加函数文件,不能添加脚本文件;在PACKAGING OPTIONS区域,若选择Runtime downloaded from web,生成的库文件只包含所添加的函数文件编译成的库文件,若选择Runtime included in package, 则除了所添加的函数文件编译成的库文件外,还需要在用户的计算机上安装MCR(参考文献1)。输入库名(Library Name)命名空间(Namespace)及类名(MassCali),点击Package,生成相应的库文件;
matlab编译后生成的库文件结构

3. 在VS项目中,引用库文件

引用所生成的库文件目录中的for_redistribution_files_only/ToolPara.dll库文件及MWArray库文件;

4. 在界面的右边“运行”按钮的成员函数中添加如下代码:
#region 测试质量质心计算模块,该模块采用matlab算法, 
// 实例化质量质心计算类的对象: massCali
ToolPara.MassCali massCali = new ToolPara.MassCali();

//计算结果
//随机测试,用于测试算法, 输入的数据来自随机产生
MWStructArray result = (MWStructArray)massCali.test_mass_calibration();

//输出结果
this.MassByLib = ((MWNumericArray)result["mass"])[1, 1].ToScalarDouble();
this.BaryCenterByLibX = ((MWNumericArray)result["p_ee_cm"])[1, 1].ToScalarDouble();
this.BaryCenterByLibY = ((MWNumericArray)result["p_ee_cm"])[2, 1].ToScalarDouble();
this.BaryCenterByLibZ = ((MWNumericArray)result["p_ee_cm"])[3, 1].ToScalarDouble();
// 若输入的数据的维度不够,计算失败并报警
double ErrorStatus = ((MWNumericArray)result["error_status"])[1, 1].ToScalarDouble();
if (ErrorStatus == 1)
MessageBox.Show("计算失败! 输入的数据不足以支持计算,请将工具置于不同的姿态并重新计算");
#endregion

同时,需要在文件的开头,添加以下库文件:

using MathWorks.MATLAB.NET.Utility;
using MathWorks.MATLAB.NET.Arrays;

2. 调用过程中用到的几个函数

1. matlab生成的库函数的输入和输出变量类型为MWArray类型

以matlab函数

function [mass] = realtime_mass_calibration(gam, force, g, p_ee_fms, num)

为例,生成的C文件的头文件中相应的函数为:

public MWArray realtime_mass_calibration(MWArray gam, MWArray force, MWArray g, MWArray p_ee_fms);
public MWArray realtime_mass_calibration(MWArray gam, MWArray force, MWArray g);
public MWArray realtime_mass_calibration(MWArray gam, MWArray force);
public MWArray realtime_mass_calibration(MWArray gam);
public MWArray realtime_mass_calibration();
public MWArray realtime_mass_calibration(MWArray gam, MWArray force, MWArray g, MWArray p_ee_fms, MWArray num);

因此,在使用这些函数时,需要将C#变量转换为MWArray变量。

2. 由于函数的输入变量为二维数组,因此用MWArray类的间接子类MWNumericArray变量作为库函数的输入变量

首先应将需要输入和输出的变量设计成二维数组,如:

double[,] g = new double[3, 1];

然后,将变量g转换为MWNumericArray变量输入给库函数:

MWStructArray result = (MWStructArray)massCali.realtime_mass_calibration(
	(MWNumericArray)gam, 
	(MWNumericArray)force, 
	(MWNumericArray)g, 
	(MWNumericArray)p_ee_fms, 
	6);
3. 由于库函数输出的变量为一结构体 mass, 因此用MWArray的子类MWStructArray类变量作为函数的输出
//计算结果
//随机测试,用于测试算法, 输入的数据来自随机产生
//MWStructArray result = (MWStructArray)massCali.test_mass_calibration(); 
//实时工作,输入的数据gam, force来自力传感器
MWStructArray result = (MWStructArray)massCali.realtime_mass_calibration(
	(MWNumericArray)gam, 
	(MWNumericArray)force, 
	(MWNumericArray)g, 
	(MWNumericArray)p_ee_fms, 
	6);

//输出结果
this.Mass = ((MWNumericArray)result["mass"])[1, 1].ToScalarDouble();
this.BaryCenterX = ((MWNumericArray)result["p_ee_cm"])[1, 1].ToScalarDouble();
this.BaryCenterY = ((MWNumericArray)result["p_ee_cm"])[2, 1].ToScalarDouble();
this.BaryCenterZ = ((MWNumericArray)result["p_ee_cm"])[3, 1].ToScalarDouble();

3. 优缺点

这种方法将无需在用户的计算机上安装matlab软件,只需要安装matlab相应版本的编译运行时工具MCR,不同版本的matlab, MCR也不同,可在matlab的命令行中输入mcrinstaller查看帮助. 本文所用的matlab版本为matlab2014a, MCR安装文件在**\Matlab\R2014a\Toolbox\Compiler\deploy\win32\MCRInstaller.exe**. 因此这种方法比较适合部署到用户的计算机上。 缺点时开发阶段,每次matlab的算法调整,都需要重新编译成新的.dll库文件,对于开发者来说没有直接调用matlab函数方便快捷。

测试结果

VS项目运行界面如下图所示。左边部分为采用直接调用matlab函数的方法实现C#项目集成matlab代码,右边部分为调用matlab函数编译的库文件实现C#项目集成matlab代码。每次点击 运行 按钮时,程序随机产生一组数据参与计算,因此,每次运行的结果都稍有不同。当然,若随机生成的数据的秩太小而无法满足计算时,界面会做出提示并将所有结果输出为0.
测试结果图

总结

本文详细描述了直接调用matlab语句和调用matlab编译的库函数两种方法实现C#与matlab混合编程。 这两种方法中,直接调用matlab语句比较方便开发,但不利于部署到用户的计算机上;而调用matlab库文件的方法部署到用户的计算机上比较方便,但在开发时多了一步编译的过程,每次matlab程序修改后,都要重新编译一次才能被VS项目使用。

参考文献

  1. 基于MCR的MATLAB使用案例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

博士熊 - 北邮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值