最近想要实现C++与Simulink之间的通信,Simulink向C++发送数据,C++接受并且计算再发送回Simulink中。这一个简单的想法,也花了几天去实现。
实现过程
1. 找到方法
在寻找方法的时候,我发现了这个网页,里面讲述了Simulink与外界交互的方法。
链接: 将外部仿真组件集成到Simulink平台中
1.1 通过S-function 与外部应用通信介绍
在上面的网页中,找到了一个简单的例程,讲述了通过S-function 与外部应用通信。
1.2 可以按照Blog所说的方式一步一步实现
Those steps include:
Download and build the ZeroMQ library
Build a co-simulation server executable
Build a S-function to communicate with the server executable
但是因为这是2018年的例程,在实现过程中会出现一些问题。
2. 遇到问题
2.1 没有实现通过VS编译ZeroMQ library
我在下载了ZeroMQ库之后,发现build中的msvc已经被遗弃了,官方没有继续维护使用msvc 的版本,所以使用VS编译是很难成功的。
解决方法
但是,ZeroMQ已经提供了release的libzmq, 所以直接在ZeroMQ的官方github地址下载就好。
下载链接:https://github.com/zeromq/libzmq/releases/tag/v4.3.4
在下载完成后进行解压,就会发现很多 exe 文件 以及 dll文件和 lib 文件,只需要dll文件以及lib文件即可。
复制所有的dll文件和 lib 文件,放在文件路径 \ SimulinkCoSimulationExample\libzmq\bin\Win32\Debug\v140\dynamic
中,即可。
2.2 在MATLAB环境配置中出现错误
因为我在下载libzmq时是 libzmq-v142-x64-4_3_4 版本,所以在配置环境时,会出现一些问题。
解决方法
在这里还是尽量保留libzmq的版本号。 将之前的libzmq.dll
换成libzmq-v142-mt-4_3_4.dll
,如下图所示。
%% Add the ZMQ DLL to the system path:
p = simulinkproject;
if strcmp(mexext,'mexw64')
if exist(fullfile(p.RootFolder,'libzmq','bin','x64','Release','v140','dynamic','libzmq-v142-mt-4_3_4.dll'),'file')
pathEnvVar = getenv('PATH');
setenv('PATH',[pathEnvVar ';' fullfile(p.RootFolder,'libzmq','bin','x64','Release','v140','dynamic')]);
disp('libzmq-v142-mt-4_3_4.dll added to system PATH')
else
disp('libzmq-v142-mt-4_3_4.dll not found, build libzmq.dll before adding to the system path. See readme.mlx for more details.')
end
else
error('Non-Windows OS, please add the ZMQ library to your PATH environment variable manually');
end
这样就可以成功编译SetEnvVariable.m
文件 了。
同样的方法,在buildCoSimExample.m
中添加相应的lib文件即可。
p = simulinkproject;
%% Build the server App
cd(fullfile(p.RootFolder,'CoSimExample','serverApp'));
mex('-client', 'engine',...
['-I' fullfile(p.RootFolder,'CoSimExample','util')],...
['-I' fullfile(p.RootFolder,'libzmq','include')],...
['-I' fullfile(p.RootFolder,'cppzmq')],...
['-L' fullfile(p.RootFolder,'libzmq','bin','x64','Release','v140','dynamic')],...
'-llibzmq-v142-mt-4_3_4','-llibzmq-v142-mt-s-4_3_4',...
'statcalserver.cpp',...
fullfile(p.RootFolder,'CoSimExample','util','statcal_util.cpp'));
%% Build the S-function
cd(fullfile(p.RootFolder,'CoSimExample','sfun'));
mex('-I..\util',...
['-I' p.RootFolder '\libzmq\include'],...
['-I' fullfile(p.RootFolder,'libzmq','include')],...
['-I' fullfile(p.RootFolder,'cppzmq')],...
['-L' fullfile(p.RootFolder,'libzmq','bin','x64','Release','v140','dynamic')],...
'-llibzmq-v142-mt-4_3_4','-llibzmq-v142-mt-s-4_3_4',...
'statcalsfcngateway.cpp',...
'statcalclient.cpp',...
fullfile(p.RootFolder,'CoSimExample','util','statcal_util.cpp'));
cd(p.RootFolder)
编译完成。
3. 总结
多看官方文档,注意细节。
朋友们,都看到这里啦,留个赞再走吧!