MATLAB FOR PROE
MATLAB FOR PROE
作者:J_SUN_SO
e:[email protected]
1.前言
这篇文章讲的是如何在PROE中使用MATLAB,将其作为一个“计算器”嵌入到PROE,可以将PROE的参数输入到MATLAB中去,在 MATLAB中进行计算,然后提取计算结果。后期将实现以在MATLAB中调用PROE函数,这样就可以和PROE进行交互,将MATLAB的一些优化算 法等工具箱应用于PROE,这种应用将极大地提升PROE的功能。本文使用的MATLAB集成C++类库是MatGear,这是我前期的工作之一(详见 http://www.cnblogs.com/JustHaveFun-SAN/archive/2013/03/09/matGear.html), 是一个开放源代码的项目。
2.内容介绍
用到的技术除了matlab集成技术外,还用到Protoolkit菜单创建,自定义关系式函数和MFC编程技术(只用到对话框)。自定义关系式函 数请参见(http://www.protoolkit.cn/?p=537)。MFC对话框编程也相对简单,可以自己翻阅资料,本文重点阐述 MATLAB相关部分。
3.MATGEAR
MATLAB分局部和全局之分,局部引擎为每个线程启动一个独立的MATLAB线程,全局引擎则公用一个MATLAB线程,而且数据都是共享的,本文将使用全局引擎。MATGEAR中的引擎集成类MEngine 如下:
class MEngine { public: //初始化函数的bSingleUse=1表示启动一个局部引擎,bSingleUse=0表示启动全局引擎。 MEngine(BOOL bSingleUse=0);// bSingleUse=0启动全局引擎,计算空间数据共享 virtual ~MEngine(); BOOL IsEngineOpen();//是否候已经打开引擎 BOOL IsSingleUse();//是否是局部引擎 BOOL OpenEngine();//打开引擎 BOOL CloseEngine();//关闭引擎 void SetEngineVisible(BOOL bVisible);//设置引擎是否可见 BOOL GetEngineVisible(); void PutVar(char *name,MatlabData* d);//向MATLAB输入参数 BOOL GetVar(char *name,MatlabData** d);// 获取MATLAB参数 //执行命令 void EvalString(char* matlabString); const char* GetOutPut();//执行命令后的反馈输出 protected: Engine *m_matlabEng; int m_bInit; char m_OutBuffer[MAX_OUT_PUT];//局部matlab输出 static char g_OutBuffer[MAX_OUT_PUT];//全局malab输出 int m_bSingleUse;//是否独立开启一个matlab线程,否则将共享一个MATLAB线程。 };
4.自定义关系函数
主要的调用过程为:启动MATLAB->交互(设置变量,读取变量,画曲线…)->关闭MATLAB。
定义的函数接口如下:
MAT_OPEN() | 打开MATLAB引擎,重复调用将添加引用计数,只有调用相应次数的MAT_CLOSE才能关闭MATLAB |
MAT_CLOSE() | 关闭MATLAB |
MAT_EVAL(cmd) | 执行matlab命令 |
mat_visiable (bool) | 窗口是否可见 |
MAT_OUT_PUT() | 最近一条命令的输出 |
MAT_PUT_MAT_DOUBLE(name,double_value) | 设置或者创建matlab变量值 |
MAT_PUT_INT(name,int_value) | 设置或者创建matlab变量值 |
MAT_PUT_bool(name,bool_value) | 设置或者创建matlab变量值 |
MAT_PUT_STRING(name,str_value) | 设置或者创建matlab变量值 |
MAT_IS_VAR(name) | 判断变量是否存在 |
MAT_GET_DOUBLE(name) | 获得MATLAB变量值 |
MAT_GET_INT(name) | 获得MATLAB变量值 |
MAT_GET_BOOL(name) | 获得MATLAB变量值 |
MAT_GET_STRING(name) | 获得MATLAB变量值 |
以上每个命令都对应着一个具体的结构体,整个结构体什么如下:
class user_mat_proe_func_define
{
public:
//打开MATLAB
struct m_open{
//0 输入
//1 输出:返回引用计数
static ProError Func_read (ProRelset* relset, ProMdl mdl,
char* ext_func_name, ProParamvalue* args,
ProAppData data, ProParamvalue* result);
static int UserCustomRelFuncDefine();
};
//执行命令MAT_EVAL
struct m_eval
{
//1 输入:命令表达式
//1 输出:命令输出
static ProError Func_read (ProRelset* relset, ProMdl mdl,
char* ext_func_name, ProParamvalue* args,
ProAppData data, ProParamvalue* result);
static int UserCustomRelFuncDefine();
};
//关闭MATLAB
struct m_close{
//0 输入
//1 输出:返回引用计数
static ProError Func_read (ProRelset* relset, ProMdl mdl,
char* ext_func_name, ProParamvalue* args,
ProAppData data, ProParamvalue* result);
static int UserCustomRelFuncDefine();
};
……………………..
}
以执行MATLAB命令函数为例,其具体实现代码如下:
ProError user_mat_proe_func_define::m_eval::
Func_read(ProRelset* relset, ProMdl mdl,
char* ext_func_name, ProParamvalue* args,
ProAppData data, ProParamvalue* result)
{
if (g_engine.IsEngineOpen())
{
char buf[200];
ProWstringToString(buf,args[0].value.s_val);
g_engine.EvalString(buf);
g_last_output=g_engine.GetOutPut();
}else
g_last_output=”MATLAB is not open”;
result->type = PRO_PARAM_STRING;
char buf[200];
strcpy(buf,g_last_output);
ProStringToWstring(result->value.s_val,buf);
return PRO_TK_NO_ERROR;
}
int user_mat_proe_func_define::m_eval::UserCustomRelFuncDefine()
{
ProRelfuncArg* args_array;
/*———————————————————————*\
1个变量,类型均为string,输入不能忽略
\*———————————————————————*/
ProArrayAlloc (1, sizeof (ProRelfuncArg), 1, (ProArray*)&args_array);
args_array [0].type = PRO_PARAM_STRING;
args_array [0].attributes = PRO_RELF_ATTR_NONE;
/*———————————————————————*\
注册函数,只注册读函数,写函数忽略
\*———————————————————————*/
ProRelationFunctionRegister (“mat_eval”, args_array,
Func_read, NULL, NULL,
PRO_B_FALSE, NULL);
return (PRO_TK_NO_ERROR);
}
5.函数注册
在初始化函数中注册自定义函数:
EXTERN_C int user_initialize()
{
user_mat_proe_func_define::m_open::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_eval::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_close::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_visiable::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_put_double::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_get_double::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_put_int::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_set_int::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_put_string::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_set_string::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_is_var::UserCustomRelFuncDefine();
user_mat_proe_func_define::m_output::UserCustomRelFuncDefine();
return 0;
}
6.执行效果
此后启动PROE注册插件,可以看到关系编辑的函数列表上列出了MAT自定义函数:
在关系表达式下输入下面代码
opt=mat_open()
out_put=mat_open()
out_put=mat_eval(“x=1:0.1:10;”)
out_put=mat_eval(“y=sin(x);plot(x,y);”)
opt=mat_close()
执行后发现画出一条正弦曲线,启动matlab需要一点时间:
从matlab中提取参数也有很大用处,PROE提供的函数数量很有限,连随机数rand函数都没有,下面示范一段从matlab中提取变量的代码:
opt=mat_open()
out_put=mat_open()
out_put=mat_eval(“x=rand();”)
out_put=mat_eval(“y=floor(x*100);”)
out_put=mat_eval(“z=’[email protected]’;”)
out_put=mat_eval(“k=’j_sun_so_from_nuaa’;”)
x=mat_get_double(“x”)
y=mat_get_int(“y”)
z=mat_get_string(“z”)
k=mat_get_string(“k”)
opt=mat_close()
执行后查看参数列表,可以发现几个变量值都在上面:
——————————————————————————————————-end 2013.3.30
请发表评论